public:
static char ID; // Pass identification, replacement for typeid
explicit CodeGenPrepare(const TargetLowering *tli = 0)
- : FunctionPass(&ID), TLI(tli) {}
+ : FunctionPass(ID), TLI(tli) {}
bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
}
char CodeGenPrepare::ID = 0;
-static RegisterPass<CodeGenPrepare> X("codegenprepare",
- "Optimize for code generation");
+INITIALIZE_PASS(CodeGenPrepare, "codegenprepare",
+ "Optimize for code generation", false, false);
FunctionPass *llvm::createCodeGenPreparePass(const TargetLowering *TLI) {
return new CodeGenPrepare(TLI);
// don't mess around with them.
BasicBlock::const_iterator BBI = BB->begin();
while (const PHINode *PN = dyn_cast<PHINode>(BBI++)) {
- for (Value::use_const_iterator UI = PN->use_begin(), E = PN->use_end();
+ for (Value::const_use_iterator UI = PN->use_begin(), E = PN->use_end();
UI != E; ++UI) {
const Instruction *User = cast<Instruction>(*UI);
if (User->getParent() != DestBB || !isa<PHINode>(User))
return MadeChange;
}
+namespace {
+class CodeGenPrepareFortifiedLibCalls : public SimplifyFortifiedLibCalls {
+protected:
+ void replaceCall(Value *With) {
+ CI->replaceAllUsesWith(With);
+ CI->eraseFromParent();
+ }
+ bool isFoldable(unsigned SizeCIOp, unsigned, bool) const {
+ if (ConstantInt *SizeCI =
+ dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp)))
+ return SizeCI->isAllOnesValue();
+ return false;
+ }
+};
+} // end anonymous namespace
+
bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) {
- bool MadeChange = false;
-
// Lower all uses of llvm.objectsize.*
IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
if (II && II->getIntrinsicID() == Intrinsic::objectsize) {
- bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1);
+ bool Min = (cast<ConstantInt>(II->getArgOperand(1))->getZExtValue() == 1);
const Type *ReturnTy = CI->getType();
Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL);
CI->replaceAllUsesWith(RetVal);
const TargetData *TD = TLI ? TLI->getTargetData() : 0;
if (!TD) return false;
- // Lower all default uses of _chk calls. This is code very similar
- // to the code in InstCombineCalls, but here we are only lowering calls
+ // Lower all default uses of _chk calls. This is very similar
+ // to what InstCombineCalls does, but here we are only lowering calls
// that have the default "don't know" as the objectsize. Anything else
// should be left alone.
- StringRef Name = CI->getCalledFunction()->getName();
- BasicBlock *BB = CI->getParent();
- IRBuilder<> B(CI->getParent()->getContext());
-
- // Set the builder to the instruction after the call.
- B.SetInsertPoint(BB, CI);
-
- if (Name == "__memcpy_chk") {
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
- 1, B, TD);
- CI->replaceAllUsesWith(CI->getOperand(1));
- CI->eraseFromParent();
- return true;
- }
- return 0;
- }
-
- // Should be similar to memcpy.
- if (Name == "__mempcpy_chk") {
- return 0;
- }
-
- if (Name == "__memmove_chk") {
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- EmitMemMove(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3),
- 1, B, TD);
- CI->replaceAllUsesWith(CI->getOperand(1));
- CI->eraseFromParent();
- return true;
- }
- return 0;
- }
-
- if (Name == "__memset_chk") {
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- Value *Val = B.CreateIntCast(CI->getOperand(2), B.getInt8Ty(),
- false);
- EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B, TD);
- CI->replaceAllUsesWith(CI->getOperand(1));
- CI->eraseFromParent();
- return true;
- }
- return 0;
- }
-
- if (Name == "__strcpy_chk") {
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3));
- if (!SizeCI)
- return 0;
- // If a) we don't have any length information, or b) we know this will
- // fit then just lower to a plain strcpy. Otherwise we'll keep our
- // strcpy_chk call which may fail at runtime if the size is too long.
- // TODO: It might be nice to get a maximum length out of the possible
- // string lengths for varying.
- if (SizeCI->isAllOnesValue()) {
- Value *Ret = EmitStrCpy(CI->getOperand(1), CI->getOperand(2), B, TD);
- CI->replaceAllUsesWith(Ret);
- CI->eraseFromParent();
- return true;
- }
- return 0;
- }
-
- // Should be similar to strcpy.
- if (Name == "__stpcpy_chk") {
- return 0;
- }
-
- if (Name == "__strncpy_chk") {
- ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(4));
- if (!SizeCI)
- return 0;
- if (SizeCI->isAllOnesValue()) {
- Value *Ret = EmitStrNCpy(CI->getOperand(1), CI->getOperand(2),
- CI->getOperand(3), B, TD);
- CI->replaceAllUsesWith(Ret);
- CI->eraseFromParent();
- return true;
- }
- return 0;
- }
-
- if (Name == "__strcat_chk") {
- return 0;
- }
-
- if (Name == "__strncat_chk") {
- return 0;
- }
-
- return MadeChange;
+ CodeGenPrepareFortifiedLibCalls Simplifier;
+ return Simplifier.fold(CI, TD);
}
//===----------------------------------------------------------------------===//
// Memory Optimization
MemoryInst->replaceUsesOfWith(Addr, SunkAddr);
- if (Addr->use_empty())
+ if (Addr->use_empty()) {
RecursivelyDeleteTriviallyDeadInstructions(Addr);
+ // This address is now available for reassignment, so erase the table entry;
+ // we don't want to match some completely different instruction.
+ SunkAddrs[Addr] = 0;
+ }
return true;
}
}
// Compute the constraint code and ConstraintType to use.
- TLI->ComputeConstraintToUse(OpInfo, SDValue(),
- OpInfo.ConstraintType == TargetLowering::C_Memory);
+ TLI->ComputeConstraintToUse(OpInfo, SDValue());
if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
OpInfo.isIndirect) {