diff options
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AsmWriter.cpp | 4 | ||||
-rw-r--r-- | lib/IR/Function.cpp | 36 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 5 | ||||
-rw-r--r-- | lib/IR/TypeFinder.cpp | 3 |
4 files changed, 48 insertions, 0 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index f275305cd9..6e3b853b39 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1647,6 +1647,10 @@ void AssemblyWriter::printFunction(const Function *F) { Out << " align " << F->getAlignment(); if (F->hasGC()) Out << " gc \"" << F->getGC() << '"'; + if (F->hasPrefixData()) { + Out << " prefix "; + writeOperand(F->getPrefixData(), true); + } if (F->isDeclaration()) { Out << '\n'; } else { diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index bf9d949b89..a64a4fa64f 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -276,6 +276,9 @@ void Function::dropAllReferences() { // blockaddresses, but BasicBlock's destructor takes care of those. while (!BasicBlocks.empty()) BasicBlocks.begin()->eraseFromParent(); + + // Prefix data is stored in a side table. + setPrefixData(0); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -351,6 +354,10 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setGC(SrcF->getGC()); else clearGC(); + if (SrcF->hasPrefixData()) + setPrefixData(SrcF->getPrefixData()); + else + setPrefixData(0); } /// getIntrinsicID - This method returns the ID number of the specified @@ -720,3 +727,32 @@ bool Function::callsFunctionThatReturnsTwice() const { return false; } + +Constant *Function::getPrefixData() const { + assert(hasPrefixData()); + const LLVMContextImpl::PrefixDataMapTy &PDMap = + getContext().pImpl->PrefixDataMap; + assert(PDMap.find(this) != PDMap.end()); + return cast<Constant>(PDMap.find(this)->second->getReturnValue()); +} + +void Function::setPrefixData(Constant *PrefixData) { + if (!PrefixData && !hasPrefixData()) + return; + + unsigned SCData = getSubclassDataFromValue(); + LLVMContextImpl::PrefixDataMapTy &PDMap = getContext().pImpl->PrefixDataMap; + ReturnInst *&PDHolder = PDMap[this]; + if (PrefixData) { + if (PDHolder) + PDHolder->setOperand(0, PrefixData); + else + PDHolder = ReturnInst::Create(getContext(), PrefixData); + SCData |= 2; + } else { + delete PDHolder; + PDMap.erase(this); + SCData &= ~2; + } + setValueSubclassData(SCData); +} diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 0c659b81b7..407b985689 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -355,6 +355,11 @@ public: typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy; IntrinsicIDCacheTy IntrinsicIDCache; + /// \brief Mapping from a function to its prefix data, which is stored as the + /// operand of an unparented ReturnInst so that the prefix data has a Use. + typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy; + PrefixDataMapTy PrefixDataMap; + int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx); int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx); diff --git a/lib/IR/TypeFinder.cpp b/lib/IR/TypeFinder.cpp index d5e6203507..dd933026ea 100644 --- a/lib/IR/TypeFinder.cpp +++ b/lib/IR/TypeFinder.cpp @@ -44,6 +44,9 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { incorporateType(FI->getType()); + if (FI->hasPrefixData()) + incorporateValue(FI->getPrefixData()); + // First incorporate the arguments. for (Function::const_arg_iterator AI = FI->arg_begin(), AE = FI->arg_end(); AI != AE; ++AI) |