void TargetLoweringObjectFileCOFF::emitModuleFlags( MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const { MDNode *LinkerOptions = nullptr; for (const auto &MFE : ModuleFlags) { StringRef Key = MFE.Key->getString(); if (Key == "Linker Options") LinkerOptions = cast<MDNode>(MFE.Val); } if (LinkerOptions) { // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for // linker. MCSection *Sec = getDrectveSection(); Streamer.SwitchSection(Sec); for (const auto &Option : LinkerOptions->operands()) { for (const auto &Piece : cast<MDNode>(Option)->operands()) { // Lead with a space for consistency with our dllexport implementation. std::string Directive(" "); Directive.append(cast<MDString>(Piece)->getString()); Streamer.EmitBytes(Directive); } } } }
/// \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; }
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; }
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; }
bool Loop::isAnnotatedParallel() const { MDNode *DesiredLoopIdMetadata = getLoopID(); if (!DesiredLoopIdMetadata) return false; MDNode *ParallelAccesses = findOptionMDForLoop(this, "llvm.loop.parallel_accesses"); SmallPtrSet<MDNode *, 4> ParallelAccessGroups; // For scalable 'contains' check. if (ParallelAccesses) { for (const MDOperand &MD : drop_begin(ParallelAccesses->operands(), 1)) { MDNode *AccGroup = cast<MDNode>(MD.get()); assert(isValidAsAccessGroup(AccGroup) && "List item must be an access group"); ParallelAccessGroups.insert(AccGroup); } } // 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 belong to an access group that // is parallel to this loop. for (BasicBlock *BB : this->blocks()) { for (Instruction &I : *BB) { if (!I.mayReadOrWriteMemory()) continue; if (MDNode *AccessGroup = I.getMetadata(LLVMContext::MD_access_group)) { auto ContainsAccessGroup = [&ParallelAccessGroups](MDNode *AG) -> bool { if (AG->getNumOperands() == 0) { assert(isValidAsAccessGroup(AG) && "Item must be an access group"); return ParallelAccessGroups.count(AG); } for (const MDOperand &AccessListItem : AG->operands()) { MDNode *AccGroup = cast<MDNode>(AccessListItem.get()); assert(isValidAsAccessGroup(AccGroup) && "List item must be an access group"); if (ParallelAccessGroups.count(AccGroup)) return true; } return false; }; if (ContainsAccessGroup(AccessGroup)) 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; }
/// emitModuleFlags - Perform code emission for module flags. void TargetLoweringObjectFileMachO::emitModuleFlags( MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const { unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; MDNode *LinkerOptions = nullptr; StringRef SectionVal; for (const auto &MFE : ModuleFlags) { // Ignore flags with 'Require' behavior. if (MFE.Behavior == Module::Require) continue; StringRef Key = MFE.Key->getString(); Metadata *Val = MFE.Val; if (Key == "Objective-C Image Info Version") { VersionVal = mdconst::extract<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Garbage Collection" || Key == "Objective-C GC Only" || Key == "Objective-C Is Simulated" || Key == "Objective-C Class Properties" || Key == "Objective-C Image Swift Version") { ImageInfoFlags |= mdconst::extract<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Image Info Section") { SectionVal = cast<MDString>(Val)->getString(); } else if (Key == "Linker Options") { LinkerOptions = cast<MDNode>(Val); } } // Emit the linker options if present. if (LinkerOptions) { for (const auto &Option : LinkerOptions->operands()) { SmallVector<std::string, 4> StrOptions; for (const auto &Piece : cast<MDNode>(Option)->operands()) StrOptions.push_back(cast<MDString>(Piece)->getString()); Streamer.EmitLinkerOptions(StrOptions); } } // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. MCSectionMachO *S = getContext().getMachOSection( Segment, Section, TAA, StubSize, SectionKind::getData()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }