X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FUtils%2FCloneFunction.cpp;h=62fc2ec10b14ad8f85cbfd26a1f4d6f0c6b56dd6;hb=84bd6b0c31f41cdd1d859dab54b6bc1177c4c6bb;hp=513de4e893e9b03fcb05994290d07580304a88ac;hpb=4ee451de366474b9c228b4e5fa573795a715216d;p=oota-llvm.git diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 513de4e893e..62fc2ec10b1 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -17,11 +17,15 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/GlobalVariable.h" #include "llvm/Function.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" #include "llvm/Support/CFG.h" -#include "llvm/Support/Compiler.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/SmallVector.h" #include using namespace llvm; @@ -29,9 +33,9 @@ using namespace llvm; // CloneBasicBlock - See comments in Cloning.h BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, DenseMap &ValueMap, - const char *NameSuffix, Function *F, + const Twine &NameSuffix, Function *F, ClonedCodeInfo *CodeInfo) { - BasicBlock *NewBB = new BasicBlock("", F); + BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F); if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix); bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false; @@ -45,7 +49,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, NewBB->getInstList().push_back(NewInst); ValueMap[II] = NewInst; // Add instruction map to value. - hasCalls |= isa(II); + hasCalls |= (isa(II) && !isa(II)); if (const AllocaInst *AI = dyn_cast(II)) { if (isa(AI->getArraySize())) hasStaticAllocas = true; @@ -69,7 +73,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, // void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, DenseMap &ValueMap, - std::vector &Returns, + SmallVectorImpl &Returns, const char *NameSuffix, ClonedCodeInfo *CodeInfo) { assert(NameSuffix && "NameSuffix cannot be null!"); @@ -79,8 +83,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, assert(ValueMap.count(I) && "No mapping from source argument specified!"); #endif - // Clone the parameter attributes - NewFunc->setParamAttrs(OldFunc->getParamAttrs()); + // Clone any attributes. + if (NewFunc->arg_size() == OldFunc->arg_size()) + NewFunc->copyAttributesFrom(OldFunc); + else { + //Some arguments were deleted with the ValueMap. Copy arguments one by one + for (Function::const_arg_iterator I = OldFunc->arg_begin(), + E = OldFunc->arg_end(); I != E; ++I) + if (Argument* Anew = dyn_cast(ValueMap[I])) + Anew->addAttr( OldFunc->getAttributes() + .getParamAttributes(I->getArgNo() + 1)); + NewFunc->setAttributes(NewFunc->getAttributes() + .addAttr(0, OldFunc->getAttributes() + .getRetAttributes())); + NewFunc->setAttributes(NewFunc->getAttributes() + .addAttr(~0, OldFunc->getAttributes() + .getFnAttributes())); + + } // Loop over all of the basic blocks in the function, cloning them as // appropriate. Note that we save BE this way in order to handle cloning of @@ -135,7 +155,7 @@ Function *llvm::CloneFunction(const Function *F, ArgTypes, F->getFunctionType()->isVarArg()); // Create the new function... - Function *NewF = new Function(FTy, F->getLinkage(), F->getName()); + Function *NewF = Function::Create(FTy, F->getLinkage(), F->getName()); // Loop over the arguments, copying the names of the mapped arguments over... Function::arg_iterator DestI = NewF->arg_begin(); @@ -146,7 +166,7 @@ Function *llvm::CloneFunction(const Function *F, ValueMap[I] = DestI++; // Add mapping to ValueMap } - std::vector Returns; // Ignore returns cloned... + SmallVector Returns; // Ignore returns cloned. CloneFunctionInto(NewF, F, ValueMap, Returns, "", CodeInfo); return NewF; } @@ -156,19 +176,18 @@ Function *llvm::CloneFunction(const Function *F, namespace { /// PruningFunctionCloner - This class is a private class used to implement /// the CloneAndPruneFunctionInto method. - struct VISIBILITY_HIDDEN PruningFunctionCloner { + struct PruningFunctionCloner { Function *NewFunc; const Function *OldFunc; DenseMap &ValueMap; - std::vector &Returns; + SmallVectorImpl &Returns; const char *NameSuffix; ClonedCodeInfo *CodeInfo; const TargetData *TD; - public: PruningFunctionCloner(Function *newFunc, const Function *oldFunc, DenseMap &valueMap, - std::vector &returns, + SmallVectorImpl &returns, const char *nameSuffix, ClonedCodeInfo *codeInfo, const TargetData *td) @@ -199,7 +218,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, // Nope, clone it now. BasicBlock *NewBB; - BBEntry = NewBB = new BasicBlock(); + BBEntry = NewBB = BasicBlock::Create(BB->getContext()); if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix); bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false; @@ -214,14 +233,14 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, ValueMap[II] = C; continue; } - + Instruction *NewInst = II->clone(); if (II->hasName()) NewInst->setName(II->getName()+NameSuffix); NewBB->getInstList().push_back(NewInst); ValueMap[II] = NewInst; // Add instruction map to value. - hasCalls |= isa(II); + hasCalls |= (isa(II) && !isa(II)); if (const AllocaInst *AI = dyn_cast(II)) { if (isa(AI->getArraySize())) hasStaticAllocas = true; @@ -244,7 +263,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, // Constant fold to uncond branch! if (Cond) { BasicBlock *Dest = BI->getSuccessor(!Cond->getZExtValue()); - ValueMap[OldTI] = new BranchInst(Dest, NewBB); + ValueMap[OldTI] = BranchInst::Create(Dest, NewBB); ToClone.push_back(Dest); TerminatorDone = true; } @@ -256,7 +275,7 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, Cond = dyn_cast_or_null(ValueMap[SI->getCondition()]); if (Cond) { // Constant fold to uncond branch! BasicBlock *Dest = SI->getSuccessor(SI->findCaseValue(Cond)); - ValueMap[OldTI] = new BranchInst(Dest, NewBB); + ValueMap[OldTI] = BranchInst::Create(Dest, NewBB); ToClone.push_back(Dest); TerminatorDone = true; } @@ -299,13 +318,41 @@ ConstantFoldMappedInstruction(const Instruction *I) { else return 0; // All operands not constant! - if (const CmpInst *CI = dyn_cast(I)) - return ConstantFoldCompareInstOperands(CI->getPredicate(), - &Ops[0], Ops.size(), TD); - else - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Ops[0], Ops.size(), TD); + return ConstantFoldCompareInstOperands(CI->getPredicate(), Ops[0], Ops[1], + TD); + + if (const LoadInst *LI = dyn_cast(I)) + if (ConstantExpr *CE = dyn_cast(Ops[0])) + if (!LI->isVolatile() && CE->getOpcode() == Instruction::GetElementPtr) + if (GlobalVariable *GV = dyn_cast(CE->getOperand(0))) + if (GV->isConstant() && GV->hasDefinitiveInitializer()) + return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), + CE); + + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), &Ops[0], + Ops.size(), TD); +} + +static MDNode *UpdateInlinedAtInfo(MDNode *InsnMD, MDNode *TheCallMD) { + DILocation ILoc(InsnMD); + if (!ILoc.Verify()) return InsnMD; + + DILocation CallLoc(TheCallMD); + if (!CallLoc.Verify()) return InsnMD; + + DILocation OrigLocation = ILoc.getOrigLocation(); + MDNode *NewLoc = TheCallMD; + if (OrigLocation.Verify()) + NewLoc = UpdateInlinedAtInfo(OrigLocation.getNode(), TheCallMD); + + Value *MDVs[] = { + InsnMD->getOperand(0), // Line + InsnMD->getOperand(1), // Col + InsnMD->getOperand(2), // Scope + NewLoc + }; + return MDNode::get(InsnMD->getContext(), MDVs, 4); } /// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto, @@ -317,10 +364,11 @@ ConstantFoldMappedInstruction(const Instruction *I) { /// used for things like CloneFunction or CloneModule. void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, DenseMap &ValueMap, - std::vector &Returns, + SmallVectorImpl &Returns, const char *NameSuffix, ClonedCodeInfo *CodeInfo, - const TargetData *TD) { + const TargetData *TD, + Instruction *TheCall) { assert(NameSuffix && "NameSuffix cannot be null!"); #ifndef NDEBUG @@ -328,8 +376,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, E = OldFunc->arg_end(); II != E; ++II) assert(ValueMap.count(II) && "No mapping from source argument specified!"); #endif - - PruningFunctionCloner PFC(NewFunc, OldFunc, ValueMap, Returns, + + PruningFunctionCloner PFC(NewFunc, OldFunc, ValueMap, Returns, NameSuffix, CodeInfo, TD); // Clone the entry block, and anything recursively reachable from it. @@ -346,7 +394,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, // insert it into the new function in the right order. If not, ignore it. // // Defer PHI resolution until rest of function is resolved. - std::vector PHIToResolve; + SmallVector PHIToResolve; for (Function::const_iterator BI = OldFunc->begin(), BE = OldFunc->end(); BI != BE; ++BI) { BasicBlock *NewBB = cast_or_null(ValueMap[BI]); @@ -359,19 +407,56 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, // references as we go. This uses ValueMap to do all the hard work. // BasicBlock::iterator I = NewBB->begin(); + + unsigned DbgKind = OldFunc->getContext().getMDKindID("dbg"); + MDNode *TheCallMD = NULL; + if (TheCall && TheCall->hasMetadata()) + TheCallMD = TheCall->getMetadata(DbgKind); // Handle PHI nodes specially, as we have to remove references to dead // blocks. if (PHINode *PN = dyn_cast(I)) { // Skip over all PHI nodes, remembering them for later. BasicBlock::const_iterator OldI = BI->begin(); - for (; (PN = dyn_cast(I)); ++I, ++OldI) + for (; (PN = dyn_cast(I)); ++I, ++OldI) { + if (I->hasMetadata()) { + if (TheCallMD) { + if (MDNode *IMD = I->getMetadata(DbgKind)) { + MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD); + I->setMetadata(DbgKind, NewMD); + } + } else { + // The cloned instruction has dbg info but the call instruction + // does not have dbg info. Remove dbg info from cloned instruction. + I->setMetadata(DbgKind, 0); + } + } PHIToResolve.push_back(cast(OldI)); + } } + // FIXME: + // FIXME: + // FIXME: Unclone all this metadata stuff. + // FIXME: + // FIXME: + // Otherwise, remap the rest of the instructions normally. - for (; I != NewBB->end(); ++I) + for (; I != NewBB->end(); ++I) { + if (I->hasMetadata()) { + if (TheCallMD) { + if (MDNode *IMD = I->getMetadata(DbgKind)) { + MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD); + I->setMetadata(DbgKind, NewMD); + } + } else { + // The cloned instruction has dbg info but the call instruction + // does not have dbg info. Remove dbg info from cloned instruction. + I->setMetadata(DbgKind, 0); + } + } RemapInstruction(I, ValueMap); + } } // Defer PHI resolution until rest of function is resolved, PHI resolution @@ -391,7 +476,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) { if (BasicBlock *MappedBlock = cast_or_null(ValueMap[PN->getIncomingBlock(pred)])) { - Value *InVal = MapValue(PN->getIncomingValue(pred), ValueMap); + Value *InVal = MapValue(PN->getIncomingValue(pred), + ValueMap); assert(InVal && "Unknown input value?"); PN->setIncomingValue(pred, InVal); PN->setIncomingBlock(pred, MappedBlock);