void DIBuilder::finalizeSubprogram(DISubprogram *SP) { MDTuple *Temp = SP->getVariables().get(); if (!Temp || !Temp->isTemporary()) return; SmallVector<Metadata *, 4> Variables; auto PV = PreservedVariables.find(SP); if (PV != PreservedVariables.end()) Variables.append(PV->second.begin(), PV->second.end()); DINodeArray AV = getOrCreateArray(Variables); TempMDTuple(Temp)->replaceAllUsesWith(AV.get()); }
ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) { if (!isa<MDTuple>(MD)) return nullptr; MDTuple *Tuple = cast<MDTuple>(MD); auto &FormatMD = Tuple->getOperand(0); if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", "SampleProfile")) return getSampleProfileSummaryFromMD(Tuple); else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", "InstrProf")) return getInstrProfSummaryFromMD(Tuple); else return nullptr; }
ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) { if (!MD) return nullptr; if (!isa<MDTuple>(MD)) return nullptr; MDTuple *Tuple = cast<MDTuple>(MD); if (Tuple->getNumOperands() != 8) return nullptr; auto &FormatMD = Tuple->getOperand(0); ProfileSummary::Kind SummaryKind; if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", "SampleProfile")) SummaryKind = PSK_Sample; else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat", "InstrProf")) SummaryKind = PSK_Instr; else return nullptr; uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount, MaxInternalCount; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount", TotalCount)) return nullptr; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxCount", MaxCount)) return nullptr; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalCount", MaxInternalCount)) return nullptr; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount", MaxFunctionCount)) return nullptr; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumCounts", NumCounts)) return nullptr; if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions", NumFunctions)) return nullptr; SummaryEntryVector Summary; if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary)) return nullptr; return new ProfileSummary(SummaryKind, Summary, TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount, NumCounts, NumFunctions); }
// Parse an MDTuple representing detailed summary. static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) { if (!MD || MD->getNumOperands() != 2) return false; MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0)); if (!KeyMD || !KeyMD->getString().equals("DetailedSummary")) return false; MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1)); if (!EntriesMD) return false; for (auto &&MDOp : EntriesMD->operands()) { MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp); if (!EntryMD || EntryMD->getNumOperands() != 3) return false; ConstantAsMetadata *Op0 = dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0)); ConstantAsMetadata *Op1 = dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1)); ConstantAsMetadata *Op2 = dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2)); if (!Op0 || !Op1 || !Op2) return false; Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(), cast<ConstantInt>(Op1->getValue())->getZExtValue(), cast<ConstantInt>(Op2->getValue())->getZExtValue()); } return true; }
Optional<MDNode *> llvm::makeFollowupLoopID( MDNode *OrigLoopID, ArrayRef<StringRef> FollowupOptions, const char *InheritOptionsExceptPrefix, bool AlwaysNew) { if (!OrigLoopID) { if (AlwaysNew) return nullptr; return None; } assert(OrigLoopID->getOperand(0) == OrigLoopID); bool InheritAllAttrs = !InheritOptionsExceptPrefix; bool InheritSomeAttrs = InheritOptionsExceptPrefix && InheritOptionsExceptPrefix[0] != '\0'; SmallVector<Metadata *, 8> MDs; MDs.push_back(nullptr); bool Changed = false; if (InheritAllAttrs || InheritSomeAttrs) { for (const MDOperand &Existing : drop_begin(OrigLoopID->operands(), 1)) { MDNode *Op = cast<MDNode>(Existing.get()); auto InheritThisAttribute = [InheritSomeAttrs, InheritOptionsExceptPrefix](MDNode *Op) { if (!InheritSomeAttrs) return false; // Skip malformatted attribute metadata nodes. if (Op->getNumOperands() == 0) return true; Metadata *NameMD = Op->getOperand(0).get(); if (!isa<MDString>(NameMD)) return true; StringRef AttrName = cast<MDString>(NameMD)->getString(); // Do not inherit excluded attributes. return !AttrName.startswith(InheritOptionsExceptPrefix); }; if (InheritThisAttribute(Op)) MDs.push_back(Op); else Changed = true; } } else { // Modified if we dropped at least one attribute. Changed = OrigLoopID->getNumOperands() > 1; } bool HasAnyFollowup = false; for (StringRef OptionName : FollowupOptions) { MDNode *FollowupNode = findOptionMDForLoopID(OrigLoopID, OptionName); if (!FollowupNode) continue; HasAnyFollowup = true; for (const MDOperand &Option : drop_begin(FollowupNode->operands(), 1)) { MDs.push_back(Option.get()); Changed = true; } } // Attributes of the followup loop not specified explicity, so signal to the // transformation pass to add suitable attributes. if (!AlwaysNew && !HasAnyFollowup) return None; // If no attributes were added or remove, the previous loop Id can be reused. if (!AlwaysNew && !Changed) return OrigLoopID; // No attributes is equivalent to having no !llvm.loop metadata at all. if (MDs.size() == 1) return nullptr; // Build the new loop ID. MDTuple *FollowupLoopID = MDNode::get(OrigLoopID->getContext(), MDs); FollowupLoopID->replaceOperandWith(0, FollowupLoopID); return FollowupLoopID; }