//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/Support/CFG.h"
-#include "ValueMapper.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/ADT/SmallVector.h"
+#include <map>
using namespace llvm;
// CloneBasicBlock - See comments in Cloning.h
BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB,
- std::map<const Value*, Value*> &ValueMap,
+ DenseMap<const Value*, Value*> &ValueMap,
const char *NameSuffix, Function *F,
ClonedCodeInfo *CodeInfo) {
BasicBlock *NewBB = new BasicBlock("", F);
CodeInfo->ContainsUnwinds |= isa<UnwindInst>(BB->getTerminator());
CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas;
CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas &&
- BB != &BB->getParent()->front();
+ BB != &BB->getParent()->getEntryBlock();
}
return NewBB;
}
// ArgMap values.
//
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
- std::map<const Value*, Value*> &ValueMap,
+ DenseMap<const Value*, Value*> &ValueMap,
std::vector<ReturnInst*> &Returns,
const char *NameSuffix, ClonedCodeInfo *CodeInfo) {
assert(NameSuffix && "NameSuffix cannot be null!");
assert(ValueMap.count(I) && "No mapping from source argument specified!");
#endif
+ // Clone the parameter attributes
+ NewFunc->setParamAttrs(OldFunc->getParamAttrs());
+
// 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
// recursive functions into themselves.
/// the function from their old to new values.
///
Function *llvm::CloneFunction(const Function *F,
- std::map<const Value*, Value*> &ValueMap,
+ DenseMap<const Value*, Value*> &ValueMap,
ClonedCodeInfo *CodeInfo) {
std::vector<const Type*> ArgTypes;
namespace {
/// PruningFunctionCloner - This class is a private class used to implement
/// the CloneAndPruneFunctionInto method.
- struct PruningFunctionCloner {
+ struct VISIBILITY_HIDDEN PruningFunctionCloner {
Function *NewFunc;
const Function *OldFunc;
- std::map<const Value*, Value*> &ValueMap;
+ DenseMap<const Value*, Value*> &ValueMap;
std::vector<ReturnInst*> &Returns;
const char *NameSuffix;
ClonedCodeInfo *CodeInfo;
public:
PruningFunctionCloner(Function *newFunc, const Function *oldFunc,
- std::map<const Value*, Value*> &valueMap,
+ DenseMap<const Value*, Value*> &valueMap,
std::vector<ReturnInst*> &returns,
const char *nameSuffix,
ClonedCodeInfo *codeInfo,
/// CloneBlock - The specified block is found to be reachable, clone it and
/// anything that it can reach.
- void CloneBlock(const BasicBlock *BB);
+ void CloneBlock(const BasicBlock *BB,
+ std::vector<const BasicBlock*> &ToClone);
public:
/// ConstantFoldMappedInstruction - Constant fold the specified instruction,
/// CloneBlock - The specified block is found to be reachable, clone it and
/// anything that it can reach.
-void PruningFunctionCloner::CloneBlock(const BasicBlock *BB) {
+void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
+ std::vector<const BasicBlock*> &ToClone){
Value *&BBEntry = ValueMap[BB];
// Have we already cloned this block?
if (Cond) {
BasicBlock *Dest = BI->getSuccessor(!Cond->getZExtValue());
ValueMap[OldTI] = new BranchInst(Dest, NewBB);
- CloneBlock(Dest);
+ ToClone.push_back(Dest);
TerminatorDone = true;
}
}
if (Cond) { // Constant fold to uncond branch!
BasicBlock *Dest = SI->getSuccessor(SI->findCaseValue(Cond));
ValueMap[OldTI] = new BranchInst(Dest, NewBB);
- CloneBlock(Dest);
+ ToClone.push_back(Dest);
TerminatorDone = true;
}
}
// Recursively clone any reachable successor blocks.
const TerminatorInst *TI = BB->getTerminator();
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
- CloneBlock(TI->getSuccessor(i));
+ ToClone.push_back(TI->getSuccessor(i));
}
if (CodeInfo) {
else
return 0; // All operands not constant!
- return ConstantFoldInstOperands(I, &Ops[0], Ops.size(), TD);
+
+ if (const CmpInst *CI = dyn_cast<CmpInst>(I))
+ return ConstantFoldCompareInstOperands(CI->getPredicate(),
+ &Ops[0], Ops.size(), TD);
+ else
+ return ConstantFoldInstOperands(I->getOpcode(), I->getType(),
+ &Ops[0], Ops.size(), TD);
}
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
/// effect of this is to copy significantly less code in cases where (for
/// example) a function call with constant arguments is inlined, and those
/// constant arguments cause a significant amount of code in the callee to be
-/// dead. Since this doesn't produce an exactly copy of the input, it can't be
+/// dead. Since this doesn't produce an exact copy of the input, it can't be
/// used for things like CloneFunction or CloneModule.
void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
- std::map<const Value*, Value*> &ValueMap,
+ DenseMap<const Value*, Value*> &ValueMap,
std::vector<ReturnInst*> &Returns,
const char *NameSuffix,
ClonedCodeInfo *CodeInfo,
NameSuffix, CodeInfo, TD);
// Clone the entry block, and anything recursively reachable from it.
- PFC.CloneBlock(&OldFunc->getEntryBlock());
+ std::vector<const BasicBlock*> CloneWorklist;
+ CloneWorklist.push_back(&OldFunc->getEntryBlock());
+ while (!CloneWorklist.empty()) {
+ const BasicBlock *BB = CloneWorklist.back();
+ CloneWorklist.pop_back();
+ PFC.CloneBlock(BB, CloneWorklist);
+ }
// Loop over all of the basic blocks in the old function. If the block was
// reachable, we have cloned it and the old block is now in the value map:
PN->eraseFromParent();
++OldI;
}
- } else if (PN->getNumIncomingValues() == 1) {
- BasicBlock::iterator I = NewBB->begin();
- BasicBlock::const_iterator OldI = OldBB->begin();
- while ((PN = dyn_cast<PHINode>(I++))) {
- Value *NV = PN->getIncomingValue(0);
- PN->replaceAllUsesWith(NV);
- assert(ValueMap[OldI] == PN && "ValueMap mismatch");
- ValueMap[OldI] = NV;
- PN->eraseFromParent();
- ++OldI;
- }
}
+ // NOTE: We cannot eliminate single entry phi nodes here, because of
+ // ValueMap. Single entry phi nodes can have multiple ValueMap entries
+ // pointing at them. Thus, deleting one would require scanning the ValueMap
+ // to update any entries in it that would require that. This would be
+ // really slow.
}
// Now that the inlined function body has been fully constructed, go through
BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
if (!BI || BI->isConditional()) { ++I; continue; }
+ // Note that we can't eliminate uncond branches if the destination has
+ // single-entry PHI nodes. Eliminating the single-entry phi nodes would
+ // require scanning the ValueMap to update any entries that point to the phi
+ // node.
BasicBlock *Dest = BI->getSuccessor(0);
- if (!Dest->getSinglePredecessor()) { ++I; continue; }
+ if (!Dest->getSinglePredecessor() || isa<PHINode>(Dest->begin())) {
+ ++I; continue;
+ }
// We know all single-entry PHI nodes in the inlined function have been
// removed, so we just need to splice the blocks.