X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FWriter%2FValueEnumerator.cpp;h=cae20a86af9ff40350e4cbdafb8871c62caa86c6;hb=dad20b2ae2544708d6a33abdb9bddd0a329f50e0;hp=22b7f52387a427164d09366cc020b609f9d04d33;hpb=bb660fc192c341012f5f1686b6792be807a6d38b;p=oota-llvm.git diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 22b7f52387a..cae20a86af9 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -326,6 +326,12 @@ ValueEnumerator::ValueEnumerator(const Module &M) { if (I->hasPrologueData()) EnumerateValue(I->getPrologueData()); + // Enumerate the metadata type. + // + // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode + // only encodes the metadata type when it's used as a value. + EnumerateType(Type::getMetadataTy(M.getContext())); + // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M.getValueSymbolTable()); @@ -341,11 +347,17 @@ ValueEnumerator::ValueEnumerator(const Module &M) { for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Use &Op : I.operands()) { - if (MDNode *MD = dyn_cast(&Op)) - if (MD->isFunctionLocal() && MD->getFunction()) - // These will get enumerated during function-incorporation. - continue; - EnumerateOperandType(Op); + auto *MD = dyn_cast(&Op); + if (!MD) { + EnumerateOperandType(Op); + continue; + } + + // Local metadata is enumerated during function-incorporation. + if (isa(MD->getMetadata())) + continue; + + EnumerateMetadata(MD->getMetadata()); } EnumerateType(I.getType()); if (const CallInst *CI = dyn_cast(&I)) @@ -389,17 +401,20 @@ void ValueEnumerator::setInstructionID(const Instruction *I) { } unsigned ValueEnumerator::getValueID(const Value *V) const { - if (isa(V) || isa(V)) { - ValueMapType::const_iterator I = MDValueMap.find(V); - assert(I != MDValueMap.end() && "Value not in slotcalculator!"); - return I->second-1; - } + if (auto *MD = dyn_cast(V)) + return getMetadataID(MD->getMetadata()); ValueMapType::const_iterator I = ValueMap.find(V); assert(I != ValueMap.end() && "Value not in slotcalculator!"); return I->second-1; } +unsigned ValueEnumerator::getMetadataID(const Metadata *MD) const { + auto I = MDValueMap.find(MD); + assert(I != MDValueMap.end() && "Metadata not in slotcalculator!"); + return I->second - 1; +} + void ValueEnumerator::dump() const { print(dbgs(), ValueMap, "Default"); dbgs() << '\n'; @@ -436,6 +451,18 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map, } } +void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map, + const char *Name) const { + + OS << "Map Name: " << Name << "\n"; + OS << "Size: " << Map.size() << "\n"; + for (auto I = Map.begin(), E = Map.end(); I != E; ++I) { + const Metadata *MD = I->first; + OS << "Metadata: slot = " << I->second << "\n"; + MD->dump(); + } +} + /// OptimizeConstants - Reorder constant pool for denser encoding. void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { if (CstStart == CstEnd || CstStart+1 == CstEnd) return; @@ -493,25 +520,24 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { /// and types referenced by the given MDNode. void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (Value *V = N->getOperand(i)) { - if (isa(V) || isa(V)) - EnumerateMetadata(V); - else if (!isa(V) && !isa(V)) - EnumerateValue(V); - } else + Metadata *MD = N->getOperand(i); + if (!MD) { EnumerateType(Type::getVoidTy(N->getContext())); + continue; + } + assert(!isa(MD) && "MDNodes cannot be function-local"); + if (auto *C = dyn_cast(MD)) { + EnumerateValue(C->getValue()); + continue; + } + EnumerateMetadata(MD); } } -void ValueEnumerator::EnumerateMetadata(const Value *MD) { - assert((isa(MD) || isa(MD)) && "Invalid metadata kind"); - - // Skip function-local nodes themselves, but walk their operands. - const MDNode *N = dyn_cast(MD); - if (N && N->isFunctionLocal() && N->getFunction()) { - EnumerateMDNodeOperands(N); - return; - } +void ValueEnumerator::EnumerateMetadata(const Metadata *MD) { + assert( + (isa(MD) || isa(MD) || isa(MD)) && + "Invalid metadata kind"); // Insert a dummy ID to block the co-recursive call to // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph. @@ -520,55 +546,39 @@ void ValueEnumerator::EnumerateMetadata(const Value *MD) { if (!MDValueMap.insert(std::make_pair(MD, 0)).second) return; - // Enumerate the type of this value. - EnumerateType(MD->getType()); - // Visit operands first to minimize RAUW. - if (N) + if (auto *N = dyn_cast(MD)) EnumerateMDNodeOperands(N); + else if (auto *C = dyn_cast(MD)) + EnumerateValue(C->getValue()); // Replace the dummy ID inserted above with the correct one. MDValueMap may // have changed by inserting operands, so we need a fresh lookup here. - MDValues.push_back(MD); - MDValueMap[MD] = MDValues.size(); + MDs.push_back(MD); + MDValueMap[MD] = MDs.size(); } /// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata -/// information reachable from the given MDNode. -void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { - assert(N->isFunctionLocal() && N->getFunction() && - "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); - - // Enumerate the type of this value. - EnumerateType(N->getType()); - +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalMetadata( + const LocalAsMetadata *Local) { // Check to see if it's already in! - unsigned &MDValueID = MDValueMap[N]; + unsigned &MDValueID = MDValueMap[Local]; if (MDValueID) return; - MDValues.push_back(N); - MDValueID = MDValues.size(); - - // To incoroporate function-local information visit all function-local - // MDNodes and all function-local values they reference. - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - if (Value *V = N->getOperand(i)) { - if (MDNode *O = dyn_cast(V)) { - if (O->isFunctionLocal() && O->getFunction()) - EnumerateFunctionLocalMetadata(O); - } else if (isa(V) || isa(V)) - EnumerateValue(V); - } + MDs.push_back(Local); + MDValueID = MDs.size(); + + EnumerateValue(Local->getValue()); - // Also, collect all function-local MDNodes for easy access. - FunctionLocalMDs.push_back(N); + // Also, collect all function-local metadata for easy access. + FunctionLocalMDs.push_back(Local); } void ValueEnumerator::EnumerateValue(const Value *V) { assert(!V->getType()->isVoidTy() && "Can't insert void values!"); - assert(!isa(V) && !isa(V) && - "EnumerateValue doesn't handle Metadata!"); + assert(!isa(V) && "EnumerateValue doesn't handle Metadata!"); // Check to see if it's already in! unsigned &ValueID = ValueMap[V]; @@ -657,30 +667,35 @@ void ValueEnumerator::EnumerateType(Type *Ty) { void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateType(V->getType()); - if (const Constant *C = dyn_cast(V)) { - // If this constant is already enumerated, ignore it, we know its type must - // be enumerated. - if (ValueMap.count(V)) return; + if (auto *MD = dyn_cast(V)) { + assert(!isa(MD->getMetadata()) && + "Function-local metadata should be left for later"); - // This constant may have operands, make sure to enumerate the types in - // them. - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - const Value *Op = C->getOperand(i); + EnumerateMetadata(MD->getMetadata()); + return; + } - // Don't enumerate basic blocks here, this happens as operands to - // blockaddress. - if (isa(Op)) continue; + const Constant *C = dyn_cast(V); + if (!C) + return; - EnumerateOperandType(Op); - } + // If this constant is already enumerated, ignore it, we know its type must + // be enumerated. + if (ValueMap.count(C)) + return; - if (const MDNode *N = dyn_cast(V)) { - for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) - if (Value *Elem = N->getOperand(i)) - EnumerateOperandType(Elem); - } - } else if (isa(V) || isa(V)) - EnumerateMetadata(V); + // This constant may have operands, make sure to enumerate the types in + // them. + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + const Value *Op = C->getOperand(i); + + // Don't enumerate basic blocks here, this happens as operands to + // blockaddress. + if (isa(Op)) + continue; + + EnumerateOperandType(Op); + } } void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { @@ -708,7 +723,7 @@ void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { void ValueEnumerator::incorporateFunction(const Function &F) { InstructionCount = 0; NumModuleValues = Values.size(); - NumModuleMDValues = MDValues.size(); + NumModuleMDs = MDs.size(); // Adding function arguments to the value table. for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); @@ -739,24 +754,16 @@ void ValueEnumerator::incorporateFunction(const Function &F) { FirstInstID = Values.size(); - SmallVector FnLocalMDVector; + SmallVector FnLocalMDVector; // Add all of the instructions. for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) { - if (MDNode *MD = dyn_cast(*OI)) - if (MD->isFunctionLocal() && MD->getFunction()) + if (auto *MD = dyn_cast(&*OI)) + if (auto *Local = dyn_cast(MD->getMetadata())) // Enumerate metadata after the instructions they might refer to. - FnLocalMDVector.push_back(MD); - } - - SmallVector, 8> MDs; - I->getAllMetadataOtherThanDebugLoc(MDs); - for (unsigned i = 0, e = MDs.size(); i != e; ++i) { - MDNode *N = MDs[i].second; - if (N->isFunctionLocal() && N->getFunction()) - FnLocalMDVector.push_back(N); + FnLocalMDVector.push_back(Local); } if (!I->getType()->isVoidTy()) @@ -773,13 +780,13 @@ void ValueEnumerator::purgeFunction() { /// Remove purged values from the ValueMap. for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) ValueMap.erase(Values[i].first); - for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) - MDValueMap.erase(MDValues[i]); + for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i) + MDValueMap.erase(MDs[i]); for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) ValueMap.erase(BasicBlocks[i]); Values.resize(NumModuleValues); - MDValues.resize(NumModuleMDValues); + MDs.resize(NumModuleMDs); BasicBlocks.clear(); FunctionLocalMDs.clear(); }