// Remove existing unroll metadata and add unroll disable metadata to // indicate the loop has already been unrolled. This prevents a loop // from being unrolled more than is directed by a pragma if the loop // unrolling pass is run more than once (which it generally is). static void SetLoopAlreadyUnrolled(Loop *L) { MDNode *LoopID = L->getLoopID(); // First remove any existing loop unrolling metadata. SmallVector<Metadata *, 4> MDs; // Reserve first location for self reference to the LoopID metadata node. MDs.push_back(nullptr); if (LoopID) { for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { bool IsUnrollMetadata = false; MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); if (MD) { const MDString *S = dyn_cast<MDString>(MD->getOperand(0)); IsUnrollMetadata = S && S->getString().startswith("llvm.loop.unroll."); } if (!IsUnrollMetadata) MDs.push_back(LoopID->getOperand(i)); } } // Add unroll(disable) metadata to disable future unrolling. LLVMContext &Context = L->getHeader()->getContext(); SmallVector<Metadata *, 1> DisableOperands; DisableOperands.push_back(MDString::get(Context, "llvm.loop.unroll.disable")); MDNode *DisableNode = MDNode::get(Context, DisableOperands); MDs.push_back(DisableNode); MDNode *NewLoopID = MDNode::get(Context, MDs); // Set operand 0 to refer to the loop id itself. NewLoopID->replaceOperandWith(0, NewLoopID); L->setLoopID(NewLoopID); }
/// getModuleFlagsMetadata - Returns the module flags in the provided vector. void Module:: getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const { const NamedMDNode *ModFlags = getModuleFlagsMetadata(); if (!ModFlags) return; for (unsigned i = 0, e = ModFlags->getNumOperands(); i != e; ++i) { MDNode *Flag = ModFlags->getOperand(i); ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0)); MDString *Key = cast<MDString>(Flag->getOperand(1)); Value *Val = Flag->getOperand(2); Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), Key, Val)); } }
void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) { ActiveLoops.push_back(L); if (!IsParallel) return; BasicBlock *Header = L->getHeader(); MDNode *Id = getID(Header->getContext()); assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference"); assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id"); MDNode *Ids = ParallelLoops.empty() ? Id : MDNode::concatenate(ParallelLoops.back(), Id); ParallelLoops.push_back(Ids); }
bool MDNodeMapper::createPOT(UniquedGraph &G, const MDNode &FirstN) { assert(G.Info.empty() && "Expected a fresh traversal"); assert(FirstN.isUniqued() && "Expected uniqued node in POT"); // Construct a post-order traversal of the uniqued subgraph under FirstN. bool AnyChanges = false; SmallVector<POTWorklistEntry, 16> Worklist; Worklist.push_back(POTWorklistEntry(const_cast<MDNode &>(FirstN))); (void)G.Info[&FirstN]; while (!Worklist.empty()) { // Start or continue the traversal through the this node's operands. auto &WE = Worklist.back(); if (MDNode *N = visitOperands(G, WE.Op, WE.N->op_end(), WE.HasChanged)) { // Push a new node to traverse first. Worklist.push_back(POTWorklistEntry(*N)); continue; } // Push the node onto the POT. assert(WE.N->isUniqued() && "Expected only uniqued nodes"); assert(WE.Op == WE.N->op_end() && "Expected to visit all operands"); auto &D = G.Info[WE.N]; AnyChanges |= D.HasChanged = WE.HasChanged; D.ID = G.POT.size(); G.POT.push_back(WE.N); // Pop the node off the worklist. Worklist.pop_back(); } return AnyChanges; }
void RuntimeHelperFixupPass::FixArrayInit(Function *F) { Module *M = F->getParent(); LLVMContext &ctx = F->getContext(); for (auto it = F->use_begin(), end = F->use_end(); it != end; ++it) { CallInst *CI = dyn_cast<CallInst>(*it); assert (CI && "Unknown usage for array init helper"); Instruction *field_runtime_handle = dyn_cast<Instruction>(CI->getArgOperand(1)); assert (field_runtime_handle); MDNode *md = field_runtime_handle->getMetadata("silk_runtime_field_handle"); assert (md); ConstantInt *handle = dyn_cast<ConstantInt>(md->getOperand(0)); assert(handle); auto vm_field = reinterpret_cast<VMField*>(handle->getValue().getLimitedValue()); auto field_map = vm_field->field_mapping(); auto vm_named_class = dynamic_cast<VMNamedClass*>(vm_field->type()); auto size = vm_named_class->type_def()->class_size(); raw_istream is(field_map.start(), size); std::vector<uint8_t> buf; buf.resize(size); is.read((char*)buf.data(), size); Constant *predefined_value = ConstantDataArray::get(ctx, buf); auto GV = new GlobalVariable(*M, predefined_value->getType(), true, GlobalValue::InternalLinkage, predefined_value, ".initdata"); Value *array_ptr = CI->getArgOperand(0); IRBuilder<> builder(CI); auto intrinsic_array_base = intrinsic_->array_base_pointer(); auto array_ptr_casted = builder.CreateBitCast(array_ptr, builder.getInt8PtrTy()); auto array_base_ptr = builder.CreateCall(intrinsic_array_base, array_ptr_casted); builder.CreateMemCpy(array_base_ptr, GV, ConstantInt::get(Type::getInt64Ty(ctx), size), 0); CI->eraseFromParent(); } }
/// replaceAllUsesWith - Replace all uses of debug info referenced by /// this descriptor. void DIType::replaceAllUsesWith(MDNode *D) { if (!DbgNode) return; // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something // which, due to uniquing, has merged with the source. We shield clients from // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (DbgNode != D) { MDNode *Node = const_cast<MDNode*>(DbgNode); const MDNode *DN = D; const Value *V = cast_or_null<Value>(DN); Node->replaceAllUsesWith(const_cast<Value*>(V)); MDNode::deleteTemporary(Node); } }
static Optional<bool> getOptionalBoolLoopAttribute(const Loop *TheLoop, StringRef Name) { MDNode *MD = findOptionMDForLoop(TheLoop, Name); if (!MD) return None; switch (MD->getNumOperands()) { case 1: // When the value is absent it is interpreted as 'attribute set'. return true; case 2: if (ConstantInt *IntMD = mdconst::extract_or_null<ConstantInt>(MD->getOperand(1).get())) return IntMD->getZExtValue(); return true; } llvm_unreachable("unexpected number of options"); }
static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, const TargetMachine &TM) { MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); if (!MD) return nullptr; const MDOperand &Op = MD->getOperand(0); if (!Op.get()) return nullptr; auto *VM = dyn_cast<ValueAsMetadata>(Op); if (!VM) report_fatal_error("MD_associated operand is not ValueAsMetadata"); GlobalObject *OtherGO = dyn_cast<GlobalObject>(VM->getValue()); return OtherGO ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGO)) : nullptr; }
/// replaceAllUsesWith - Replace all uses of debug info referenced by /// this descriptor. After this completes, the current debug info value /// is erased. void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) { if (isNull()) return; assert (!D.isNull() && "Can not replace with null"); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something // which, due to uniquing, has merged with the source. We shield clients from // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (getNode() != D.getNode()) { MDNode *Node = DbgNode; Node->replaceAllUsesWith(D.getNode()); delete Node; } }
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 && Attrs.VectorizerUnroll == 0 && Attrs.VectorizerEnable == LoopAttributes::VecUnspecified) return nullptr; SmallVector<Value *, 4> Args; // Reserve operand 0 for loop id self reference. MDNode *TempNode = MDNode::getTemporary(Ctx, None); Args.push_back(TempNode); // Setting vectorizer.width if (Attrs.VectorizerWidth > 0) { Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"), ConstantInt::get(Type::getInt32Ty(Ctx), Attrs.VectorizerWidth) }; Args.push_back(MDNode::get(Ctx, Vals)); } // Setting vectorizer.unroll if (Attrs.VectorizerUnroll > 0) { Value *Vals[] = { MDString::get(Ctx, "llvm.loop.interleave.count"), ConstantInt::get(Type::getInt32Ty(Ctx), Attrs.VectorizerUnroll) }; Args.push_back(MDNode::get(Ctx, Vals)); } // Setting vectorizer.enable if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) { Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"), ConstantInt::get(Type::getInt1Ty(Ctx), (Attrs.VectorizerEnable == LoopAttributes::VecEnable)) }; Args.push_back(MDNode::get(Ctx, Vals)); } MDNode *LoopID = MDNode::get(Ctx, Args); assert(LoopID->use_empty() && "LoopID should not be used"); // Set the first operand to itself. LoopID->replaceOperandWith(0, LoopID); MDNode::deleteTemporary(TempNode); return LoopID; }
// Replace value from this node's operand list. void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) { Value *From = *Op; if (From == To) return; // Update the operand. Op->set(To); // If this node is already not being uniqued (because one of the operands // already went to null), then there is nothing else to do here. if (isNotUniqued()) return; LLVMContextImpl *pImpl = getType()->getContext().pImpl; // Remove "this" from the context map. FoldingSet doesn't have to reprofile // this node to remove it, so we don't care what state the operands are in. pImpl->MDNodeSet.RemoveNode(this); // If we are dropping an argument to null, we choose to not unique the MDNode // anymore. This commonly occurs during destruction, and uniquing these // brings little reuse. if (To == 0) { setIsNotUniqued(); return; } // Now that the node is out of the folding set, get ready to reinsert it. // First, check to see if another node with the same operands already exists // in the set. If it doesn't exist, this returns the position to insert it. FoldingSetNodeID ID; Profile(ID); void *InsertPoint; MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); if (N) { N->replaceAllUsesWith(this); N->destroy(); N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); assert(N == 0 && "shouldn't be in the map now!"); (void)N; } // InsertPoint will have been set by the FindNodeOrInsertPos call. pImpl->MDNodeSet.InsertNode(this, InsertPoint); }
void MDNodeMapper::remapOperands(const Data &D, MDNode &N) { for (unsigned I = 0, E = N.getNumOperands(); I != E; ++I) { Metadata *Old = N.getOperand(I); Metadata *New; if (Optional<Metadata *> MappedOp = getMappedOp(Old)){ New = *MappedOp; } else { assert(!N.isDistinct() && "Expected all nodes to be pre-mapped for distinct operands"); MDNode &OldN = *cast<MDNode>(Old); assert(!OldN.isDistinct() && "Expected distinct nodes to be pre-mapped"); New = &getFwdReference(D, OldN); } if (Old != New) N.replaceOperandWith(I, New); } }
bool MDNode::isTBAAVtableAccess() const { if (!isStructPathTBAA(this)) { if (getNumOperands() < 1) return false; if (MDString *Tag1 = dyn_cast<MDString>(getOperand(0))) { if (Tag1->getString() == "vtable pointer") return true; } return false; } // For struct-path aware TBAA, we use the access type of the tag. if (getNumOperands() < 2) return false; MDNode *Tag = cast_or_null<MDNode>(getOperand(1)); if (!Tag) return false; if (MDString *Tag1 = dyn_cast<MDString>(Tag->getOperand(0))) { if (Tag1->getString() == "vtable pointer") return true; } return false; }
/// \brief Map a distinct MDNode. /// /// Distinct nodes are not uniqued, so they must always recreated. static Metadata *mapDistinctNode(const MDNode *Node, SmallVectorImpl<MDNode *> &Cycles, ValueToValueMapTy &VM, RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer) { assert(Node->isDistinct() && "Expected distinct node"); MDNode *NewMD = MDNode::replaceWithDistinct(Node->clone()); remap(Node, NewMD, Cycles, VM, Flags, TypeMapper, Materializer); // Track any cycles beneath this node. for (Metadata *Op : NewMD->operands()) if (auto *Node = dyn_cast_or_null<MDNode>(Op)) if (!Node->isResolved()) Cycles.push_back(Node); return NewMD; }
/// createObjectPointerType - Create a new type with both the object pointer /// and artificial flags set. DIType DIBuilder::createObjectPointerType(DIType Ty) { if (Ty.isObjectPointer()) return Ty; SmallVector<Value *, 9> Elts; MDNode *N = Ty; assert (N && "Unexpected input DIType!"); for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) Elts.push_back(N->getOperand(i)); unsigned CurFlags = Ty.getFlags(); CurFlags = CurFlags | (DIType::FlagObjectPointer | DIType::FlagArtificial); // Flags are stored at this slot. Elts[8] = ConstantInt::get(Type::getInt32Ty(VMContext), CurFlags); return DIType(MDNode::get(VMContext, Elts)); }
/// @brief Get a self referencing id metadata node. /// /// The MDNode looks like this (if arg0/arg1 are not null): /// /// '!n = metadata !{metadata !n, arg0, arg1}' /// /// @return The self referencing id metadata node. static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr, Metadata *arg1 = nullptr) { MDNode *ID; SmallVector<Metadata *, 3> Args; // Use a temporary node to safely create a unique pointer for the first arg. auto TempNode = MDNode::getTemporary(Ctx, None); // Reserve operand 0 for loop id self reference. Args.push_back(TempNode.get()); if (arg0) Args.push_back(arg0); if (arg1) Args.push_back(arg1); ID = MDNode::get(Ctx, Args); ID->replaceOperandWith(0, ID); return ID; }
std::vector<Type*> lowerJuliaArrayArguments(Function *OldFunc) { Module* M = OldFunc->getParent(); LLVMContext &context = M->getContext(); NamedMDNode* JuliaArgs = M->getOrInsertNamedMetadata("julia.args"); MDNode *node = JuliaArgs->getOperand(0); int operand = 0; std::vector<Type*> ArgTypes; for (Function::const_arg_iterator I = OldFunc->arg_begin(), E = OldFunc->arg_end(); I != E; ++I) { Type* argType = I->getType(); if (is_jl_array_type(argType)) { // Gets the type from custom metadata Value *value = node->getOperand(operand); if (MDString* mdstring = dyn_cast<MDString>(value)) { if (Type* type = extractType(context, mdstring->getString())) { ArgTypes.push_back(type); } else { errs() << "Could not extract type: "; mdstring->print(errs()); errs() << "\n"; exit(1); } } else { errs() << "Could not extract type: "; value->print(errs()); errs() << "\n"; exit(1); } } else { ArgTypes.push_back(I->getType()); } operand++; } return ArgTypes; }
/// Given an llvm.loop loop id metadata node, returns the loop hint metadata /// node with the given name (for example, "llvm.loop.unroll.count"). If no /// such metadata node exists, then nullptr is returned. MDNode *llvm::GetUnrollMetadata(MDNode *LoopID, StringRef Name) { // First operand should refer to the loop id itself. assert(LoopID->getNumOperands() > 0 && "requires at least one operand"); assert(LoopID->getOperand(0) == LoopID && "invalid loop id"); for (unsigned i = 1, e = LoopID->getNumOperands(); i < e; ++i) { MDNode *MD = dyn_cast<MDNode>(LoopID->getOperand(i)); if (!MD) continue; MDString *S = dyn_cast<MDString>(MD->getOperand(0)); if (!S) continue; if (Name.equals(S->getString())) return MD; } return nullptr; }
void AddressSanitizer::FindDynamicInitializers(Module& M) { // Clang generates metadata identifying all dynamically initialized globals. NamedMDNode *DynamicGlobals = M.getNamedMetadata("llvm.asan.dynamically_initialized_globals"); if (!DynamicGlobals) return; for (int i = 0, n = DynamicGlobals->getNumOperands(); i < n; ++i) { MDNode *MDN = DynamicGlobals->getOperand(i); assert(MDN->getNumOperands() == 1); Value *VG = MDN->getOperand(0); // The optimizer may optimize away a global entirely, in which case we // cannot instrument access to it. if (!VG) continue; GlobalVariable *G = cast<GlobalVariable>(VG); DynamicallyInitializedGlobals.insert(G); } }
/// categorizeModuleFlagNodes - bool ModuleLinker:: categorizeModuleFlagNodes(const NamedMDNode *ModFlags, DenseMap<MDString*, MDNode*> &ErrorNode, DenseMap<MDString*, MDNode*> &WarningNode, DenseMap<MDString*, MDNode*> &OverrideNode, DenseMap<MDString*, SmallSetVector<MDNode*, 8> > &RequireNodes, SmallSetVector<MDString*, 16> &SeenIDs) { bool HasErr = false; for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { MDNode *Op = ModFlags->getOperand(I); assert(Op->getNumOperands() == 3 && "Invalid module flag metadata!"); assert(isa<ConstantInt>(Op->getOperand(0)) && "Module flag's first operand must be an integer!"); assert(isa<MDString>(Op->getOperand(1)) && "Module flag's second operand must be an MDString!"); ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); MDString *ID = cast<MDString>(Op->getOperand(1)); Value *Val = Op->getOperand(2); switch (Behavior->getZExtValue()) { default: assert(false && "Invalid behavior in module flag metadata!"); break; case Module::Error: { MDNode *&ErrNode = ErrorNode[ID]; if (!ErrNode) ErrNode = Op; if (ErrNode->getOperand(2) != Val) HasErr = emitError("linking module flags '" + ID->getString() + "': IDs have conflicting values"); break; } case Module::Warning: { MDNode *&WarnNode = WarningNode[ID]; if (!WarnNode) WarnNode = Op; if (WarnNode->getOperand(2) != Val) errs() << "WARNING: linking module flags '" << ID->getString() << "': IDs have conflicting values"; break; } case Module::Require: RequireNodes[ID].insert(Op); break; case Module::Override: { MDNode *&OvrNode = OverrideNode[ID]; if (!OvrNode) OvrNode = Op; if (OvrNode->getOperand(2) != Val) HasErr = emitError("linking module flags '" + ID->getString() + "': IDs have conflicting override values"); break; } } SeenIDs.insert(ID); } return HasErr; }
static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && Attrs.InterleaveCount == 0 && Attrs.VectorizeEnable == LoopAttributes::Unspecified) return nullptr; SmallVector<Metadata *, 4> Args; // Reserve operand 0 for loop id self reference. auto TempNode = MDNode::getTemporary(Ctx, None); Args.push_back(TempNode.get()); // Setting vectorize.width if (Attrs.VectorizeWidth > 0) { Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"), ConstantAsMetadata::get(ConstantInt::get( Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))}; Args.push_back(MDNode::get(Ctx, Vals)); } // Setting interleave.count if (Attrs.InterleaveCount > 0) { Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"), ConstantAsMetadata::get(ConstantInt::get( Type::getInt32Ty(Ctx), Attrs.InterleaveCount))}; Args.push_back(MDNode::get(Ctx, Vals)); } // Setting vectorize.enable if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) { Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"), ConstantAsMetadata::get(ConstantInt::get( Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable == LoopAttributes::Enable)))}; Args.push_back(MDNode::get(Ctx, Vals)); } // Set the first operand to itself. MDNode *LoopID = MDNode::get(Ctx, Args); LoopID->replaceOperandWith(0, LoopID); return LoopID; }
bool Loop::isAnnotatedParallel() const { MDNode *desiredLoopIdMetadata = getLoopID(); if (!desiredLoopIdMetadata) return false; // The loop branch contains the parallel loop metadata. In order to ensure // that any parallel-loop-unaware optimization pass hasn't added loop-carried // dependencies (thus converted the loop back to a sequential loop), check // that all the memory instructions in the loop contain parallelism metadata // that point to the same unique "loop id metadata" the loop branch does. for (block_iterator BB = block_begin(), BE = block_end(); BB != BE; ++BB) { for (BasicBlock::iterator II = (*BB)->begin(), EE = (*BB)->end(); II != EE; II++) { if (!II->mayReadOrWriteMemory()) continue; // The memory instruction can refer to the loop identifier metadata // directly or indirectly through another list metadata (in case of // nested parallel loops). The loop identifier metadata refers to // itself so we can check both cases with the same routine. MDNode *loopIdMD = II->getMetadata(LLVMContext::MD_mem_parallel_loop_access); if (!loopIdMD) return false; bool loopIdMDFound = false; for (unsigned i = 0, e = loopIdMD->getNumOperands(); i < e; ++i) { if (loopIdMD->getOperand(i) == desiredLoopIdMetadata) { loopIdMDFound = true; break; } } if (!loopIdMDFound) return false; } } return true; }
std::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) { if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { MDNode *N = GCov->getOperand(i); if (N->getNumOperands() != 2) continue; MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); if (!GCovFile || !CompileUnit) continue; if (CompileUnit == CU) { SmallString<128> Filename = GCovFile->getString(); sys::path::replace_extension(Filename, NewStem); return Filename.str(); } } } SmallString<128> Filename = CU.getFilename(); sys::path::replace_extension(Filename, NewStem); return sys::path::filename(Filename.str()); }
/// Remap the operands of an MDNode. static bool remapOperands(MDNode &Node, SmallVectorImpl<MDNode *> &DistinctWorklist, ValueToValueMapTy &VM, RemapFlags Flags, ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer) { assert(!Node.isUniqued() && "Expected temporary or distinct node"); bool AnyChanged = false; for (unsigned I = 0, E = Node.getNumOperands(); I != E; ++I) { Metadata *Old = Node.getOperand(I); Metadata *New = mapMetadataOp(Old, DistinctWorklist, VM, Flags, TypeMapper, Materializer); if (Old != New) { AnyChanged = true; Node.replaceOperandWith(I, New); } } return AnyChanged; }
/// \brief Set input string into loop metadata by keeping other values intact. void llvm::addStringMetadataToLoop(Loop *TheLoop, const char *MDString, unsigned V) { SmallVector<Metadata *, 4> MDs(1); // If the loop already has metadata, retain it. MDNode *LoopID = TheLoop->getLoopID(); if (LoopID) { for (unsigned i = 1, ie = LoopID->getNumOperands(); i < ie; ++i) { MDNode *Node = cast<MDNode>(LoopID->getOperand(i)); MDs.push_back(Node); } } // Add new metadata. MDs.push_back(createStringMetadata(TheLoop, MDString, V)); // Replace current metadata node with new one. LLVMContext &Context = TheLoop->getHeader()->getContext(); MDNode *NewLoopID = MDNode::get(Context, MDs); // Set operand 0 to refer to the loop id itself. NewLoopID->replaceOperandWith(0, NewLoopID); TheLoop->setLoopID(NewLoopID); }
MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) { // To ensure uniqueness the root node is self-referential. auto Dummy = MDNode::getTemporary(Context, None); SmallVector<Metadata *, 3> Args(1, Dummy.get()); if (Extra) Args.push_back(Extra); if (!Name.empty()) Args.push_back(createString(Name)); MDNode *Root = MDNode::get(Context, Args); // At this point we have // !0 = metadata !{} <- dummy // !1 = metadata !{metadata !0} <- root // Replace the dummy operand with the root node itself and delete the dummy. Root->replaceOperandWith(0, Root); // We now have // !1 = metadata !{metadata !1} <- self-referential root return Root; }
static bool HasTBAAPointerAccess(Value *V) { auto *I = dyn_cast<Instruction>(V); if (!I) return false; MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa); if (!Tag) return false; if (Tag->getNumOperands() < 2) return false; MDNode *Type = dyn_cast_or_null<MDNode>(Tag->getOperand(1)); if (!Type) return false; if (auto *TypeName = dyn_cast<MDString>(Type->getOperand(0))) if (TypeName->getString() == "any pointer") return true; return false; }
bool Loop::isAnnotatedParallel() const { MDNode *DesiredLoopIdMetadata = getLoopID(); if (!DesiredLoopIdMetadata) return false; // The loop branch contains the parallel loop metadata. In order to ensure // that any parallel-loop-unaware optimization pass hasn't added loop-carried // dependencies (thus converted the loop back to a sequential loop), check // that all the memory instructions in the loop contain parallelism metadata // that point to the same unique "loop id metadata" the loop branch does. for (BasicBlock *BB : this->blocks()) { for (Instruction &I : *BB) { if (!I.mayReadOrWriteMemory()) continue; // The memory instruction can refer to the loop identifier metadata // directly or indirectly through another list metadata (in case of // nested parallel loops). The loop identifier metadata refers to // itself so we can check both cases with the same routine. MDNode *LoopIdMD = I.getMetadata(LLVMContext::MD_mem_parallel_loop_access); if (!LoopIdMD) return false; bool LoopIdMDFound = false; for (const MDOperand &MDOp : LoopIdMD->operands()) { if (MDOp == DesiredLoopIdMetadata) { LoopIdMDFound = true; break; } } if (!LoopIdMDFound) return false; } } return true; }
// Propagate existing explicit probabilities from either profile data or // 'expect' intrinsic processing. bool BranchProbabilityInfo::calcMetadataWeights(BasicBlock *BB) { TerminatorInst *TI = BB->getTerminator(); //rigel DEBUG(dbgs() << "Rigel - inside BranchProbabilityInfo::calcMetadataWeights. BB: "<<BB->getName()<<"\n"); DEBUG(dbgs() << "Rigel - inside BranchProbabilityInfo::calcMetadataWeights. TI: "<<*TI<<"\n"); DEBUG(dbgs() << "Rigel - inside BranchProbabilityInfo::calcMetadataWeights. TI->getNumSuccessors(): "<<TI->getNumSuccessors()<<"\n"); //end rigel if (TI->getNumSuccessors() == 1) return false; if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI)) return false; MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof); if (!WeightsNode) return false; // Ensure there are weights for all of the successors. Note that the first // operand to the metadata node is a name, not a weight. if (WeightsNode->getNumOperands() != TI->getNumSuccessors() + 1) return false; // Build up the final weights that will be used in a temporary buffer, but // don't add them until all weihts are present. Each weight value is clamped // to [1, getMaxWeightFor(BB)]. uint32_t WeightLimit = getMaxWeightFor(BB); SmallVector<uint32_t, 2> Weights; Weights.reserve(TI->getNumSuccessors()); for (unsigned i = 1, e = WeightsNode->getNumOperands(); i != e; ++i) { ConstantInt *Weight = dyn_cast<ConstantInt>(WeightsNode->getOperand(i)); if (!Weight) return false; Weights.push_back( std::max<uint32_t>(1, Weight->getLimitedValue(WeightLimit))); } assert(Weights.size() == TI->getNumSuccessors() && "Checked above"); for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) setEdgeWeight(BB, i, Weights[i]); return true; }
void TargetLoweringObjectFileCOFF:: emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, Mangler &Mang, const TargetMachine &TM) const { MDNode *LinkerOptions = nullptr; // Look for the "Linker Options" flag, since it's the only one we support. for (ArrayRef<Module::ModuleFlagEntry>::iterator i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { const Module::ModuleFlagEntry &MFE = *i; StringRef Key = MFE.Key->getString(); Metadata *Val = MFE.Val; if (Key == "Linker Options") { LinkerOptions = cast<MDNode>(Val); break; } } if (!LinkerOptions) return; // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for linker. const MCSection *Sec = getDrectveSection(); Streamer.SwitchSection(Sec); for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i)); for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); // Lead with a space for consistency with our dllexport implementation. std::string Directive(" "); Directive.append(MDOption->getString()); Streamer.EmitBytes(Directive); } } }