diff options
| author | Alex Zinenko <zinenko@google.com> | 2019-12-02 03:27:38 -0800 |
|---|---|---|
| committer | A. Unique TensorFlower <gardener@tensorflow.org> | 2019-12-02 03:28:10 -0800 |
| commit | d5e627f84b440cb4dd30802930629ea970dd4342 (patch) | |
| tree | 13d3a929445b6e260759eb3ecdc92a247225c08f /mlir/lib/Target/LLVMIR | |
| parent | 2235333d5878393ca4d43891184c3f58f71edeb5 (diff) | |
| download | bcm5719-llvm-d5e627f84b440cb4dd30802930629ea970dd4342.tar.gz bcm5719-llvm-d5e627f84b440cb4dd30802930629ea970dd4342.zip | |
Introduce Linkage attribute to the LLVM dialect
LLVM IR supports linkage on global objects such as global variables and
functions. Introduce the Linkage attribute into the LLVM dialect, backed by an
integer storage. Use this attribute on LLVM::GlobalOp and make it mandatory.
Implement parsing/printing of the attribute and conversion to LLVM IR.
See tensorflow/mlir#277.
PiperOrigin-RevId: 283309328
Diffstat (limited to 'mlir/lib/Target/LLVMIR')
| -rw-r--r-- | mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp | 38 | ||||
| -rw-r--r-- | mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 39 |
2 files changed, 71 insertions, 6 deletions
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp index fd4e4134d8b..6cf975bcce2 100644 --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -215,6 +215,37 @@ Attribute Importer::getConstantAsAttr(llvm::Constant *value) { return Attribute(); } +/// Converts LLVM global variable linkage type into the LLVM dialect predicate. +static LLVM::Linkage +processLinkage(llvm::GlobalVariable::LinkageTypes linkage) { + switch (linkage) { + case llvm::GlobalValue::PrivateLinkage: + return LLVM::Linkage::Private; + case llvm::GlobalValue::InternalLinkage: + return LLVM::Linkage::Internal; + case llvm::GlobalValue::AvailableExternallyLinkage: + return LLVM::Linkage::AvailableExternally; + case llvm::GlobalValue::LinkOnceAnyLinkage: + return LLVM::Linkage::Linkonce; + case llvm::GlobalValue::WeakAnyLinkage: + return LLVM::Linkage::Weak; + case llvm::GlobalValue::CommonLinkage: + return LLVM::Linkage::Common; + case llvm::GlobalValue::AppendingLinkage: + return LLVM::Linkage::Appending; + case llvm::GlobalValue::ExternalWeakLinkage: + return LLVM::Linkage::ExternWeak; + case llvm::GlobalValue::LinkOnceODRLinkage: + return LLVM::Linkage::LinkonceODR; + case llvm::GlobalValue::WeakODRLinkage: + return LLVM::Linkage::WeakODR; + case llvm::GlobalValue::ExternalLinkage: + return LLVM::Linkage::External; + } + + llvm_unreachable("unhandled linkage type"); +} + GlobalOp Importer::processGlobal(llvm::GlobalVariable *GV) { auto it = globals.find(GV); if (it != globals.end()) @@ -224,9 +255,10 @@ GlobalOp Importer::processGlobal(llvm::GlobalVariable *GV) { Attribute valueAttr; if (GV->hasInitializer()) valueAttr = getConstantAsAttr(GV->getInitializer()); - GlobalOp op = b.create<GlobalOp>(UnknownLoc::get(context), - processType(GV->getValueType()), - GV->isConstant(), GV->getName(), valueAttr); + GlobalOp op = b.create<GlobalOp>( + UnknownLoc::get(context), processType(GV->getValueType()), + GV->isConstant(), processLinkage(GV->getLinkage()), GV->getName(), + valueAttr); if (GV->hasInitializer() && !valueAttr) { Region &r = op.getInitializerRegion(); currentEntryBlock = b.createBlock(&r); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 7f3ce5a738f..f985fed3991 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -279,6 +279,35 @@ LogicalResult ModuleTranslation::convertBlock(Block &bb, bool ignoreArguments) { return success(); } +// Convert the LLVM dialect linkage type to LLVM IR linkage type. +llvm::GlobalVariable::LinkageTypes convertLinkageType(LLVM::Linkage linkage) { + switch (linkage) { + case LLVM::Linkage::Private: + return llvm::GlobalValue::PrivateLinkage; + case LLVM::Linkage::Internal: + return llvm::GlobalValue::InternalLinkage; + case LLVM::Linkage::AvailableExternally: + return llvm::GlobalValue::AvailableExternallyLinkage; + case LLVM::Linkage::Linkonce: + return llvm::GlobalValue::LinkOnceAnyLinkage; + case LLVM::Linkage::Weak: + return llvm::GlobalValue::WeakAnyLinkage; + case LLVM::Linkage::Common: + return llvm::GlobalValue::CommonLinkage; + case LLVM::Linkage::Appending: + return llvm::GlobalValue::AppendingLinkage; + case LLVM::Linkage::ExternWeak: + return llvm::GlobalValue::ExternalWeakLinkage; + case LLVM::Linkage::LinkonceODR: + return llvm::GlobalValue::LinkOnceODRLinkage; + case LLVM::Linkage::WeakODR: + return llvm::GlobalValue::WeakODRLinkage; + case LLVM::Linkage::External: + return llvm::GlobalValue::ExternalLinkage; + } + llvm_unreachable("unknown linkage type"); +} + // Create named global variables that correspond to llvm.mlir.global // definitions. void ModuleTranslation::convertGlobals() { @@ -308,11 +337,15 @@ void ModuleTranslation::convertGlobals() { cst = cast<llvm::Constant>(valueMapping.lookup(ret.getOperand(0))); } + auto linkage = convertLinkageType(op.linkage()); + bool anyExternalLinkage = + (linkage == llvm::GlobalVariable::ExternalLinkage || + linkage == llvm::GlobalVariable::ExternalWeakLinkage); auto addrSpace = op.addr_space().getLimitedValue(); auto *var = new llvm::GlobalVariable( - *llvmModule, type, op.constant(), llvm::GlobalValue::InternalLinkage, - cst, op.sym_name(), /*InsertBefore=*/nullptr, - llvm::GlobalValue::NotThreadLocal, addrSpace); + *llvmModule, type, op.constant(), linkage, + anyExternalLinkage ? nullptr : cst, op.sym_name(), + /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace); globalsMapping.try_emplace(op, var); } |

