diff options
Diffstat (limited to 'llvm/lib/Linker/IRMover.cpp')
| -rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index b475ea81d107..5a819e2d736c 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -9,19 +9,24 @@ #include "llvm/Linker/IRMover.h" #include "LinkDiagnosticInfo.h" #include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/Function.h" #include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Module.h" #include "llvm/IR/PseudoProbe.h" #include "llvm/IR/TypeFinder.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Support/Error.h" #include "llvm/Support/Path.h" -#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/ValueMapper.h" #include <utility> using namespace llvm; @@ -381,7 +386,7 @@ class IRLinker { std::unique_ptr<Module> SrcM; /// See IRMover::move(). - std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor; + IRMover::LazyCallback AddLazyFor; TypeMapTy TypeMap; GlobalValueMaterializer GValMaterializer; @@ -524,8 +529,7 @@ public: IRLinker(Module &DstM, MDMapT &SharedMDs, IRMover::IdentifiedStructTypeSet &Set, std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink, - std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor, - bool IsPerformingImport) + IRMover::LazyCallback AddLazyFor, bool IsPerformingImport) : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(std::move(AddLazyFor)), TypeMap(Set), GValMaterializer(*this), LValMaterializer(*this), SharedMDs(SharedMDs), IsPerformingImport(IsPerformingImport), @@ -987,10 +991,11 @@ bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) { // Callback to the client to give a chance to lazily add the Global to the // list of value to link. bool LazilyAdded = false; - AddLazyFor(SGV, [this, &LazilyAdded](GlobalValue &GV) { - maybeAdd(&GV); - LazilyAdded = true; - }); + if (AddLazyFor) + AddLazyFor(SGV, [this, &LazilyAdded](GlobalValue &GV) { + maybeAdd(&GV); + LazilyAdded = true; + }); return LazilyAdded; } @@ -1041,7 +1046,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV, if (Function *F = dyn_cast<Function>(NewGV)) if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F)) { NewGV->eraseFromParent(); - NewGV = Remangled.getValue(); + NewGV = *Remangled; NeedsRenaming = false; } @@ -1229,8 +1234,15 @@ void IRLinker::linkNamedMDNodes() { continue; // Don't import pseudo probe descriptors here for thinLTO. They will be // emitted by the originating module. - if (IsPerformingImport && NMD.getName() == PseudoProbeDescMetadataName) + if (IsPerformingImport && NMD.getName() == PseudoProbeDescMetadataName) { + if (!DstM.getNamedMetadata(NMD.getName())) + emitWarning("Pseudo-probe ignored: source module '" + + SrcM->getModuleIdentifier() + + "' is compiled with -fpseudo-probe-for-profiling while " + "destination module '" + + DstM.getModuleIdentifier() + "' is not\n"); continue; + } NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName()); // Add Src elements into Dest node. for (const MDNode *Op : NMD.operands()) @@ -1245,6 +1257,9 @@ Error IRLinker::linkModuleFlagsMetadata() { if (!SrcModFlags) return Error::success(); + // Check for module flag for updates before do anything. + UpgradeModuleFlags(*SrcM); + // If the destination module doesn't have module flags yet, then just copy // over the source module's flags. NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata(); @@ -1327,11 +1342,15 @@ Error IRLinker::linkModuleFlagsMetadata() { // Diagnose inconsistent merge behavior types. if (SrcBehaviorValue != DstBehaviorValue) { + bool MinAndWarn = (SrcBehaviorValue == Module::Min && + DstBehaviorValue == Module::Warning) || + (DstBehaviorValue == Module::Min && + SrcBehaviorValue == Module::Warning); bool MaxAndWarn = (SrcBehaviorValue == Module::Max && DstBehaviorValue == Module::Warning) || (DstBehaviorValue == Module::Max && SrcBehaviorValue == Module::Warning); - if (!MaxAndWarn) + if (!(MaxAndWarn || MinAndWarn)) return stringErr("linking module flags '" + ID->getString() + "': IDs have conflicting behaviors in '" + SrcM->getModuleIdentifier() + "' and '" + @@ -1360,6 +1379,25 @@ Error IRLinker::linkModuleFlagsMetadata() { emitWarning(Str); } + // Choose the minimum if either source or destination request Min behavior. + if (DstBehaviorValue == Module::Min || SrcBehaviorValue == Module::Min) { + ConstantInt *DstValue = + mdconst::extract<ConstantInt>(DstOp->getOperand(2)); + ConstantInt *SrcValue = + mdconst::extract<ConstantInt>(SrcOp->getOperand(2)); + + // The resulting flag should have a Min behavior, and contain the minimum + // value from between the source and destination values. + Metadata *FlagOps[] = { + (DstBehaviorValue != Module::Min ? SrcOp : DstOp)->getOperand(0), ID, + (SrcValue->getZExtValue() < DstValue->getZExtValue() ? SrcOp : DstOp) + ->getOperand(2)}; + MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps); + DstModFlags->setOperand(DstIndex, Flag); + Flags[ID].first = Flag; + continue; + } + // Choose the maximum if either source or destination request Max behavior. if (DstBehaviorValue == Module::Max || SrcBehaviorValue == Module::Max) { ConstantInt *DstValue = @@ -1673,10 +1711,9 @@ IRMover::IRMover(Module &M) : Composite(M) { } } -Error IRMover::move( - std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink, - std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor, - bool IsPerformingImport) { +Error IRMover::move(std::unique_ptr<Module> Src, + ArrayRef<GlobalValue *> ValuesToLink, + LazyCallback AddLazyFor, bool IsPerformingImport) { IRLinker TheIRLinker(Composite, SharedMDs, IdentifiedStructTypes, std::move(Src), ValuesToLink, std::move(AddLazyFor), IsPerformingImport); |
