aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Linker/IRMover.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Linker/IRMover.cpp')
-rw-r--r--llvm/lib/Linker/IRMover.cpp69
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);