diff options
author | Vedant Kumar <vsk@apple.com> | 2015-12-19 07:30:44 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2015-12-19 07:30:44 +0000 |
commit | 34f1d639d36a40bb5817fe7241cdffab76cc4735 (patch) | |
tree | 4eac7880aabd079c3335e2e234f6ce85a9af2fc5 /lib | |
parent | 638b75bca2096456dce341ddc159d038c7e94712 (diff) |
Revert "[IR] Move optional data in llvm::Function into a hungoff uselist"
This reverts commit r256090.
This broke llvm-clang-lld-x86_64-debian-fast.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256091 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Bitcode/Writer/ValueEnumerator.cpp | 36 | ||||
-rw-r--r-- | lib/IR/AsmWriter.cpp | 18 | ||||
-rw-r--r-- | lib/IR/Function.cpp | 130 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 11 | ||||
-rw-r--r-- | lib/IR/TypeFinder.cpp | 10 | ||||
-rw-r--r-- | lib/Transforms/IPO/GlobalDCE.cpp | 10 |
6 files changed, 144 insertions, 71 deletions
diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index faf82a7926e..2a9b4490ffb 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -87,9 +87,15 @@ static OrderMap orderModule(const Module &M) { if (!isa<GlobalValue>(A.getAliasee())) orderValue(A.getAliasee(), OM); for (const Function &F : M) { - for (const Use &U : F.operands()) - if (!isa<GlobalValue>(U.get())) - orderValue(U.get(), OM); + if (F.hasPrefixData()) + if (!isa<GlobalValue>(F.getPrefixData())) + orderValue(F.getPrefixData(), OM); + if (F.hasPrologueData()) + if (!isa<GlobalValue>(F.getPrologueData())) + orderValue(F.getPrologueData(), OM); + if (F.hasPersonalityFn()) + if (!isa<GlobalValue>(F.getPersonalityFn())) + orderValue(F.getPersonalityFn(), OM); } OM.LastGlobalConstantID = OM.size(); @@ -267,8 +273,12 @@ static UseListOrderStack predictUseListOrder(const Module &M) { for (const GlobalAlias &A : M.aliases()) predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack); for (const Function &F : M) { - for (const Use &U : F.operands()) - predictValueUseListOrder(U.get(), nullptr, OM, Stack); + if (F.hasPrefixData()) + predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack); + if (F.hasPrologueData()) + predictValueUseListOrder(F.getPrologueData(), nullptr, OM, Stack); + if (F.hasPersonalityFn()) + predictValueUseListOrder(F.getPersonalityFn(), nullptr, OM, Stack); } return Stack; @@ -311,10 +321,20 @@ ValueEnumerator::ValueEnumerator(const Module &M, for (const GlobalAlias &GA : M.aliases()) EnumerateValue(GA.getAliasee()); - // Enumerate any optional Function data. + // Enumerate the prefix data constants. for (const Function &F : M) - for (const Use &U : F.operands()) - EnumerateValue(U.get()); + if (F.hasPrefixData()) + EnumerateValue(F.getPrefixData()); + + // Enumerate the prologue data constants. + for (const Function &F : M) + if (F.hasPrologueData()) + EnumerateValue(F.getPrologueData()); + + // Enumerate the personality functions. + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->hasPersonalityFn()) + EnumerateValue(I->getPersonalityFn()); // Enumerate the metadata type. // diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 124fc56e78f..51a0faee81c 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -103,9 +103,17 @@ static OrderMap orderModule(const Module *M) { orderValue(&A, OM); } for (const Function &F : *M) { - for (const Use &U : F.operands()) - if (!isa<GlobalValue>(U.get())) - orderValue(U.get(), OM); + if (F.hasPrefixData()) + if (!isa<GlobalValue>(F.getPrefixData())) + orderValue(F.getPrefixData(), OM); + + if (F.hasPrologueData()) + if (!isa<GlobalValue>(F.getPrologueData())) + orderValue(F.getPrologueData(), OM); + + if (F.hasPersonalityFn()) + if (!isa<GlobalValue>(F.getPersonalityFn())) + orderValue(F.getPersonalityFn(), OM); orderValue(&F, OM); @@ -255,8 +263,8 @@ static UseListOrderStack predictUseListOrder(const Module *M) { for (const GlobalAlias &A : M->aliases()) predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack); for (const Function &F : *M) - for (const Use &U : F.operands()) - predictValueUseListOrder(U.get(), nullptr, OM, Stack); + if (F.hasPrefixData()) + predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack); return Stack; } diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index f41f7619e7d..5e4d2d2054e 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -279,6 +279,9 @@ Function::~Function() { // Remove the function from the on-the-side GC table. clearGC(); + + // FIXME: needed by operator delete + setFunctionNumOperands(1); } void Function::BuildLazyArguments() const { @@ -325,14 +328,14 @@ void Function::dropAllReferences() { while (!BasicBlocks.empty()) BasicBlocks.begin()->eraseFromParent(); - // Drop uses of any optional data (real or placeholder). - if (getNumOperands()) { - User::dropAllReferences(); - setNumHungOffUseOperands(0); - } + // Prefix and prologue data are stored in a side table. + setPrefixData(nullptr); + setPrologueData(nullptr); // Metadata is stored in a side-table. clearMetadata(); + + setPersonalityFn(nullptr); } void Function::addAttribute(unsigned i, Attribute::AttrKind attr) { @@ -422,12 +425,18 @@ void Function::copyAttributesFrom(const GlobalValue *Src) { setGC(SrcF->getGC()); else clearGC(); - if (SrcF->hasPersonalityFn()) - setPersonalityFn(SrcF->getPersonalityFn()); if (SrcF->hasPrefixData()) setPrefixData(SrcF->getPrefixData()); + else + setPrefixData(nullptr); if (SrcF->hasPrologueData()) setPrologueData(SrcF->getPrologueData()); + else + setPrologueData(nullptr); + if (SrcF->hasPersonalityFn()) + setPersonalityFn(SrcF->getPersonalityFn()); + else + setPersonalityFn(nullptr); } /// \brief This does the actual lookup of an intrinsic ID which @@ -935,67 +944,61 @@ bool Function::callsFunctionThatReturnsTwice() const { return false; } -Constant *Function::getPersonalityFn() const { - assert(hasPersonalityFn() && getNumOperands()); - return cast<Constant>(Op<0>()); -} - -void Function::setPersonalityFn(Constant *Fn) { - if (Fn) - setHungoffOperand<0>(Fn); - setValueSubclassDataBit(3, Fn != nullptr); +static Constant * +getFunctionData(const Function *F, + const LLVMContextImpl::FunctionDataMapTy &Map) { + const auto &Entry = Map.find(F); + assert(Entry != Map.end()); + return cast<Constant>(Entry->second->getReturnValue()); +} + +/// setFunctionData - Set "Map[F] = Data". Return an updated SubclassData value +/// in which Bit is low iff Data is null. +static unsigned setFunctionData(Function *F, + LLVMContextImpl::FunctionDataMapTy &Map, + Constant *Data, unsigned SCData, unsigned Bit) { + ReturnInst *&Holder = Map[F]; + if (Data) { + if (Holder) + Holder->setOperand(0, Data); + else + Holder = ReturnInst::Create(F->getContext(), Data); + return SCData | (1 << Bit); + } else { + delete Holder; + Map.erase(F); + return SCData & ~(1 << Bit); + } } Constant *Function::getPrefixData() const { - assert(hasPrefixData() && getNumOperands()); - return cast<Constant>(Op<1>()); + assert(hasPrefixData()); + return getFunctionData(this, getContext().pImpl->PrefixDataMap); } void Function::setPrefixData(Constant *PrefixData) { - if (PrefixData) - setHungoffOperand<1>(PrefixData); - setValueSubclassDataBit(1, PrefixData != nullptr); + if (!PrefixData && !hasPrefixData()) + return; + + unsigned SCData = getSubclassDataFromValue(); + SCData = setFunctionData(this, getContext().pImpl->PrefixDataMap, PrefixData, + SCData, /*Bit=*/1); + setValueSubclassData(SCData); } Constant *Function::getPrologueData() const { - assert(hasPrologueData() && getNumOperands()); - return cast<Constant>(Op<2>()); + assert(hasPrologueData()); + return getFunctionData(this, getContext().pImpl->PrologueDataMap); } void Function::setPrologueData(Constant *PrologueData) { - if (PrologueData) - setHungoffOperand<2>(PrologueData); - setValueSubclassDataBit(2, PrologueData != nullptr); -} - -void Function::allocHungoffUselist() { - // If we've already allocated a uselist, stop here. - if (getNumOperands()) + if (!PrologueData && !hasPrologueData()) return; - allocHungoffUses(3, /*IsPhi=*/ false); - setNumHungOffUseOperands(3); - - // Initialize the uselist with placeholder operands to allow traversal. - auto *CPN = ConstantPointerNull::get(Type::getInt1PtrTy(getContext(), 0)); - Op<0>().set(CPN); - Op<1>().set(CPN); - Op<2>().set(CPN); -} - -template <int Idx> -void Function::setHungoffOperand(Constant *C) { - assert(C && "Cannot set hungoff operand to nullptr"); - allocHungoffUselist(); - Op<Idx>().set(C); -} - -void Function::setValueSubclassDataBit(unsigned Bit, bool On) { - assert(Bit < 16 && "SubclassData contains only 16 bits"); - if (On) - setValueSubclassData(getSubclassDataFromValue() | (1 << Bit)); - else - setValueSubclassData(getSubclassDataFromValue() & ~(1 << Bit)); + unsigned SCData = getSubclassDataFromValue(); + SCData = setFunctionData(this, getContext().pImpl->PrologueDataMap, + PrologueData, SCData, /*Bit=*/2); + setValueSubclassData(SCData); } void Function::setEntryCount(uint64_t Count) { @@ -1013,3 +1016,22 @@ Optional<uint64_t> Function::getEntryCount() const { } return None; } + +void Function::setPersonalityFn(Constant *C) { + if (!C) { + if (hasPersonalityFn()) { + // Note, the num operands is used to compute the offset of the operand, so + // the order here matters. Clearing the operand then clearing the num + // operands ensures we have the correct offset to the operand. + Op<0>().set(nullptr); + setFunctionNumOperands(0); + } + } else { + // Note, the num operands is used to compute the offset of the operand, so + // the order here matters. We need to set num operands to 1 first so that + // we get the correct offset to the first operand when we set it. + if (!hasPersonalityFn()) + setFunctionNumOperands(1); + Op<0>().set(C); + } +} diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index a24114d0a0a..ae987e65bcb 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -1014,6 +1014,17 @@ public: /// instructions in different blocks at the same location. DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable; + typedef DenseMap<const Function *, ReturnInst *> FunctionDataMapTy; + + /// \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. + FunctionDataMapTy PrefixDataMap; + + /// \brief Mapping from a function to its prologue data, which is stored as + /// the operand of an unparented ReturnInst so that the prologue data has a + /// Use. + FunctionDataMapTy PrologueDataMap; + 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 b5bdab0865b..2ea0550ba45 100644 --- a/lib/IR/TypeFinder.cpp +++ b/lib/IR/TypeFinder.cpp @@ -44,8 +44,14 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { for (Module::const_iterator FI = M.begin(), E = M.end(); FI != E; ++FI) { incorporateType(FI->getType()); - for (const Use &U : FI->operands()) - incorporateValue(U.get()); + if (FI->hasPrefixData()) + incorporateValue(FI->getPrefixData()); + + if (FI->hasPrologueData()) + incorporateValue(FI->getPrologueData()); + + if (FI->hasPersonalityFn()) + incorporateValue(FI->getPersonalityFn()); // First incorporate the arguments. for (Function::const_arg_iterator AI = FI->arg_begin(), diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp index 9b276ed28e2..1cc657458d6 100644 --- a/lib/Transforms/IPO/GlobalDCE.cpp +++ b/lib/Transforms/IPO/GlobalDCE.cpp @@ -215,8 +215,14 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { // any globals used will be marked as needed. Function *F = cast<Function>(G); - for (Use &U : F->operands()) - MarkUsedGlobalsAsNeeded(cast<Constant>(U.get())); + if (F->hasPrefixData()) + MarkUsedGlobalsAsNeeded(F->getPrefixData()); + + if (F->hasPrologueData()) + MarkUsedGlobalsAsNeeded(F->getPrologueData()); + + if (F->hasPersonalityFn()) + MarkUsedGlobalsAsNeeded(F->getPersonalityFn()); for (BasicBlock &BB : *F) for (Instruction &I : BB) |