diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index 4b7023faef2..24e538cacf2 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -1976,7 +1976,8 @@ int main(int argc, char *argv[]) { // Set up the optimizer pipeline. // Start with registering info about how the // target lays out data structures. - fpm.add(new llvm::DataLayoutPass(*executionEngine->getDataLayout())); + module->setDataLayout(executionEngine->getDataLayout()); + fpm.add(new llvm::DataLayoutPass(module)); // Optimizations turned on #ifdef ADD_OPT_PASSES diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp index fd94592513a..a8f59428c0d 100644 --- a/examples/Kaleidoscope/Chapter4/toy.cpp +++ b/examples/Kaleidoscope/Chapter4/toy.cpp @@ -586,7 +586,8 @@ int main() { // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. - OurFPM.add(new DataLayoutPass(*TheExecutionEngine->getDataLayout())); + TheModule->setDataLayout(TheExecutionEngine->getDataLayout()); + OurFPM.add(new DataLayoutPass(TheModule)); // Provide basic AliasAnalysis support for GVN. OurFPM.add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp index 3f3f0a019c6..a31b5b4792a 100644 --- a/examples/Kaleidoscope/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/Chapter5/toy.cpp @@ -831,7 +831,8 @@ int main() { // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. - OurFPM.add(new DataLayoutPass(*TheExecutionEngine->getDataLayout())); + TheModule->setDataLayout(TheExecutionEngine->getDataLayout()); + OurFPM.add(new DataLayoutPass(TheModule)); // Provide basic AliasAnalysis support for GVN. OurFPM.add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp index c45292251d3..5a3bd2e3147 100644 --- a/examples/Kaleidoscope/Chapter6/toy.cpp +++ b/examples/Kaleidoscope/Chapter6/toy.cpp @@ -949,7 +949,8 @@ int main() { // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. - OurFPM.add(new DataLayoutPass(*TheExecutionEngine->getDataLayout())); + TheModule->setDataLayout(TheExecutionEngine->getDataLayout()); + OurFPM.add(new DataLayoutPass(TheModule)); // Provide basic AliasAnalysis support for GVN. OurFPM.add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp index 48d24c0508d..c2c337c9008 100644 --- a/examples/Kaleidoscope/Chapter7/toy.cpp +++ b/examples/Kaleidoscope/Chapter7/toy.cpp @@ -1113,7 +1113,8 @@ int main() { // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. - OurFPM.add(new DataLayoutPass(*TheExecutionEngine->getDataLayout())); + TheModule->setDataLayout(TheExecutionEngine->getDataLayout()); + OurFPM.add(new DataLayoutPass(TheModule)); // Provide basic AliasAnalysis support for GVN. OurFPM.add(createBasicAliasAnalysisPass()); // Promote allocas to registers. diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index ab1d500b732..a9d8d313e45 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -99,7 +99,6 @@ public: /// \brief Cost analyzer used by inliner. class InlineCostAnalysis : public CallGraphSCCPass { - const DataLayout *DL; const TargetTransformInfo *TTI; public: diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 3bdc95d556f..1adc254a61e 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -116,6 +116,8 @@ public: const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } + const DataLayout *getDataLayout() const; + /// \brief Returns the terminator instruction if the block is well formed or /// null if the block is not well formed. TerminatorInst *getTerminator(); diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index 046553dc1a2..5bdfc498751 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -460,10 +460,10 @@ public: const DataLayout &getDataLayout() const { return DL; } + // For use with the C API. C++ code should always use the constructor that + // takes a module. explicit DataLayoutPass(const DataLayout &DL); - explicit DataLayoutPass(StringRef LayoutDescription); - explicit DataLayoutPass(const Module *M); static char ID; // Pass identification, replacement for typeid diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index f0c80673be1..32108b153cd 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -300,6 +300,8 @@ public: inline Module *getParent() { return Parent; } inline const Module *getParent() const { return Parent; } + const DataLayout *getDataLayout() const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 0a245483ff7..8ba8b9c4f1a 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -53,6 +53,8 @@ public: inline const BasicBlock *getParent() const { return Parent; } inline BasicBlock *getParent() { return Parent; } + const DataLayout *getDataLayout() const; + /// removeFromParent - This method unlinks 'this' from the containing basic /// block, but does not delete it. /// diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp index 53faae5c671..6d700b9db8b 100644 --- a/lib/Analysis/IPA/InlineCost.cpp +++ b/lib/Analysis/IPA/InlineCost.cpp @@ -399,6 +399,7 @@ bool CallAnalyzer::visitBitCast(BitCastInst &I) { } bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) { + const DataLayout *DL = I.getDataLayout(); // Propagate constants through ptrtoint. Constant *COp = dyn_cast(I.getOperand(0)); if (!COp) @@ -435,6 +436,7 @@ bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) { } bool CallAnalyzer::visitIntToPtr(IntToPtrInst &I) { + const DataLayout *DL = I.getDataLayout(); // Propagate constants through ptrtoint. Constant *COp = dyn_cast(I.getOperand(0)); if (!COp) @@ -1203,7 +1205,7 @@ INITIALIZE_PASS_END(InlineCostAnalysis, "inline-cost", "Inline Cost Analysis", char InlineCostAnalysis::ID = 0; -InlineCostAnalysis::InlineCostAnalysis() : CallGraphSCCPass(ID), DL(0) {} +InlineCostAnalysis::InlineCostAnalysis() : CallGraphSCCPass(ID) {} InlineCostAnalysis::~InlineCostAnalysis() {} @@ -1214,8 +1216,6 @@ void InlineCostAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { } bool InlineCostAnalysis::runOnSCC(CallGraphSCC &SCC) { - DataLayoutPass *DLP = getAnalysisIfAvailable(); - DL = DLP ? &DLP->getDataLayout() : 0; TTI = &getAnalysis(); return false; } @@ -1273,7 +1273,7 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee, DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName() << "...\n"); - CallAnalyzer CA(DL, *TTI, *Callee, Threshold); + CallAnalyzer CA(Callee->getDataLayout(), *TTI, *Callee, Threshold); bool ShouldInline = CA.analyzeCall(CS); DEBUG(CA.dump()); diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 2836218d4a4..b271618a5ff 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" @@ -151,7 +152,8 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, // Add target data MutexGuard locked(lock); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayoutPass(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory that // may be executed. @@ -183,7 +185,8 @@ void JIT::addModule(Module *M) { jitstate = new JITState(M); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayoutPass(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory // that may be executed. @@ -214,7 +217,8 @@ bool JIT::removeModule(Module *M) { jitstate = new JITState(Modules[0]); FunctionPassManager &PM = jitstate->getPM(locked); - PM.add(new DataLayoutPass(*TM.getDataLayout())); + M->setDataLayout(TM.getDataLayout()); + PM.add(new DataLayoutPass(M)); // Turn the machine code intermediate representation into bytes in memory // that may be executed. diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index ad11a839f0d..a0dfbef51f3 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -142,7 +142,8 @@ ObjectBufferStream* MCJIT::emitObject(Module *M) { PassManager PM; - PM.add(new DataLayoutPass(*TM->getDataLayout())); + M->setDataLayout(TM->getDataLayout()); + PM.add(new DataLayoutPass(M)); // The RuntimeDyld will take ownership of this shortly OwningPtr CompiledObject(new ObjectBufferStream()); diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index 41e58ec5da2..1d7db917915 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -30,6 +30,10 @@ ValueSymbolTable *BasicBlock::getValueSymbolTable() { return 0; } +const DataLayout *BasicBlock::getDataLayout() const { + return getParent()->getDataLayout(); +} + LLVMContext &BasicBlock::getContext() const { return getType()->getContext(); } diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index ccdaec5e554..bddb6807512 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -786,10 +786,6 @@ DataLayoutPass::DataLayoutPass(const DataLayout &DL) initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); } -DataLayoutPass::DataLayoutPass(StringRef Str) : ImmutablePass(ID), DL(Str) { - initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); -} - DataLayoutPass::DataLayoutPass(const Module *M) : ImmutablePass(ID), DL(M) { initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); } diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 5ad96b2ce3a..ee882c3eace 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -40,6 +40,10 @@ void GlobalValue::Dematerialize() { getParent()->Dematerialize(this); } +const DataLayout *GlobalValue::getDataLayout() const { + return getParent()->getDataLayout(); +} + /// Override destroyConstant to make sure it doesn't get called on /// GlobalValue's because they shouldn't be treated like other constants. void GlobalValue::destroyConstant() { diff --git a/lib/IR/Instruction.cpp b/lib/IR/Instruction.cpp index a7773c47168..fd5bcc904fb 100644 --- a/lib/IR/Instruction.cpp +++ b/lib/IR/Instruction.cpp @@ -35,6 +35,10 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, } } +const DataLayout *Instruction::getDataLayout() const { + return getParent()->getDataLayout(); +} + Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(0) { diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index b18726b98df..c5f98736c00 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -482,7 +482,8 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, passes.add(createVerifierPass()); // Add an appropriate DataLayout instance for this module... - passes.add(new DataLayoutPass(*TargetMach->getDataLayout())); + mergedModule->setDataLayout(TargetMach->getDataLayout()); + passes.add(new DataLayoutPass(mergedModule)); // Add appropriate TargetLibraryInfo for this module. passes.add(new TargetLibraryInfo(Triple(TargetMach->getTargetTriple()))); @@ -503,7 +504,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, PassManager codeGenPasses; - codeGenPasses.add(new DataLayoutPass(*TargetMach->getDataLayout())); + codeGenPasses.add(new DataLayoutPass(mergedModule)); formatted_raw_ostream Out(out); diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp index ee5178184fb..627786dfb49 100644 --- a/lib/Target/Target.cpp +++ b/lib/Target/Target.cpp @@ -55,6 +55,8 @@ LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep) { } void LLVMAddTargetData(LLVMTargetDataRef TD, LLVMPassManagerRef PM) { + // The DataLayoutPass must now be in sync with the module. Unfortunatelly we + // cannot enforce that from the C api. unwrap(PM)->add(new DataLayoutPass(*unwrap(TD))); } diff --git a/lib/Target/TargetMachineC.cpp b/lib/Target/TargetMachineC.cpp index e939b88e0a0..a2829d4c027 100644 --- a/lib/Target/TargetMachineC.cpp +++ b/lib/Target/TargetMachineC.cpp @@ -212,7 +212,8 @@ static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, *ErrorMessage = strdup(error.c_str()); return true; } - pass.add(new DataLayoutPass(*td)); + Mod->setDataLayout(td); + pass.add(new DataLayoutPass(Mod)); TargetMachine::CodeGenFileType ft; switch (codegen) { diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 5b311cb6173..bb72f252fe4 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -299,9 +299,8 @@ static int compileModule(char **argv, LLVMContext &Context) { // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getDataLayout()) - PM.add(new DataLayoutPass(*DL)); - else - PM.add(new DataLayoutPass(mod)); + mod->setDataLayout(DL); + PM.add(new DataLayoutPass(mod)); // Override default to generate verbose assembly. Target.setAsmVerbosityDefault(true); diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 2b209d99c74..169e648e2eb 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -430,11 +430,13 @@ int main(int argc, char **argv) { // Add an appropriate DataLayout instance for this module. const DataLayout *DL = M.get()->getDataLayout(); - if (!DL && !DefaultDataLayout.empty()) - DL = new DataLayout(DefaultDataLayout); + if (!DL && !DefaultDataLayout.empty()) { + M->setDataLayout(DefaultDataLayout); + DL = M.get()->getDataLayout(); + } if (DL) - Passes.add(new DataLayoutPass(*DL)); + Passes.add(new DataLayoutPass(M.get())); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; @@ -450,7 +452,7 @@ int main(int argc, char **argv) { if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (DL) - FPasses->add(new DataLayoutPass(*DL)); + FPasses->add(new DataLayoutPass(M.get())); if (TM.get()) TM->addAnalysisPasses(*FPasses);