diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -223,6 +223,7 @@ /// Returns the code model. The choices are small, kernel, medium, large, and /// target default. CodeModel::Model getCodeModel() const; + void setCodeModel(CodeModel::Model CM); bool isPositionIndependent() const; diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -71,6 +71,9 @@ /// target default. CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; } +/// Set the code model. +void TargetMachine::setCodeModel(CodeModel::Model CM) { CMModel = CM; } + /// Get the IR-specified TLS model for Var. static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) { switch (GV->getThreadLocalMode()) { diff --git a/llvm/test/tools/llc/codemodel.ll b/llvm/test/tools/llc/codemodel.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llc/codemodel.ll @@ -0,0 +1,18 @@ +; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK-LARGE + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 1, !"Code Model", i32 4} + +@data = internal constant [0 x i32] [] + +define i32* @foo() nounwind readonly { +entry: +; CHECK-LARGE-LABEL: foo: +; CHECK-LARGE: movabsq $data, %rax + ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0) +} diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -521,6 +521,7 @@ }; Optional RM = codegen::getExplicitRelocModel(); + Optional CM = codegen::getExplicitCodeModel(); const Target *TheTarget = nullptr; std::unique_ptr Target; @@ -553,8 +554,7 @@ InitializeOptions(TheTriple); Target = std::unique_ptr(TheTarget->createTargetMachine( - TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, - codegen::getExplicitCodeModel(), OLvl)); + TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl)); assert(Target && "Could not allocate target machine!"); return Target->createDataLayout().getStringRepresentation(); @@ -574,6 +574,11 @@ } if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); + + Optional CM_IR = M->getCodeModel(); + if (!CM.hasValue() && CM_IR.hasValue()) { + Target->setCodeModel(CM_IR.getValue()); + } } else { TheTriple = Triple(Triple::normalize(TargetTriple)); if (TheTriple.getTriple().empty()) @@ -598,8 +603,7 @@ InitializeOptions(TheTriple); Target = std::unique_ptr(TheTarget->createTargetMachine( - TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, - codegen::getExplicitCodeModel(), OLvl)); + TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl)); assert(Target && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down