summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/IR/Module.h12
-rw-r--r--llvm/lib/IR/Module.cpp19
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp8
-rw-r--r--llvm/test/LTO/X86/Inputs/codemodel-3.ll16
-rw-r--r--llvm/test/LTO/X86/codemodel-1.ll20
-rw-r--r--llvm/test/LTO/X86/codemodel-2.ll20
-rw-r--r--llvm/test/LTO/X86/codemodel-3.ll20
7 files changed, 114 insertions, 1 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index a405f7df3ef..91e44addbd6 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -16,6 +16,7 @@
#define LLVM_IR_MODULE_H
#include "llvm-c/Types.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -840,6 +841,17 @@ public:
void setPIELevel(PIELevel::Level PL);
/// @}
+ /// @}
+ /// @name Utility function for querying and setting code model
+ /// @{
+
+ /// Returns the code model (tiny, small, kernel, medium or large model)
+ Optional<CodeModel::Model> getCodeModel() const;
+
+ /// Set the code model (tiny, small, kernel, medium or large)
+ void setCodeModel(CodeModel::Model CL);
+ /// @}
+
/// @name Utility functions for querying and setting PGO summary
/// @{
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 882ab106a37..7d02a3956ff 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -13,6 +13,7 @@
#include "llvm/IR/Module.h"
#include "SymbolTableListTraitsImpl.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -507,6 +508,24 @@ void Module::setPIELevel(PIELevel::Level PL) {
addModuleFlag(ModFlagBehavior::Max, "PIE Level", PL);
}
+Optional<CodeModel::Model> Module::getCodeModel() const {
+ auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("Code Model"));
+
+ if (!Val)
+ return None;
+
+ return static_cast<CodeModel::Model>(
+ cast<ConstantInt>(Val->getValue())->getZExtValue());
+}
+
+void Module::setCodeModel(CodeModel::Model CL) {
+ // Linking object files with different code models is undefined behavior
+ // because the compiler would have to generate additional code (to span
+ // longer jumps) if a larger code model is used with a smaller one.
+ // Therefore we will treat attempts to mix code models as an error.
+ addModuleFlag(ModFlagBehavior::Error, "Code Model", CL);
+}
+
void Module::setProfileSummary(Metadata *M) {
addModuleFlag(ModFlagBehavior::Error, "ProfileSummary", M);
}
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index eadbb410bd5..be33ab84933 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -138,9 +138,15 @@ createTargetMachine(Config &Conf, const Target *TheTarget, Module &M) {
RelocModel =
M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_;
+ Optional<CodeModel::Model> CodeModel;
+ if (Conf.CodeModel)
+ CodeModel = *Conf.CodeModel;
+ else
+ CodeModel = M.getCodeModel();
+
return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel,
- Conf.CodeModel, Conf.CGOptLevel));
+ CodeModel, Conf.CGOptLevel));
}
static void runNewPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
diff --git a/llvm/test/LTO/X86/Inputs/codemodel-3.ll b/llvm/test/LTO/X86/Inputs/codemodel-3.ll
new file mode 100644
index 00000000000..7b264af6f48
--- /dev/null
+++ b/llvm/test/LTO/X86/Inputs/codemodel-3.ll
@@ -0,0 +1,16 @@
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-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 1}
+
+%struct.rtx_def = type { i16, i16 }
+
+define void @bar(%struct.rtx_def* %a, i8 %b, i32 %c) {
+ call void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def* align 4 %a, i8 %b, i32 %c, i1 true)
+ ret void
+}
+
+declare void @llvm.memset.p0struct.rtx_def.i32(%struct.rtx_def*, i8, i32, i1)
diff --git a/llvm/test/LTO/X86/codemodel-1.ll b/llvm/test/LTO/X86/codemodel-1.ll
new file mode 100644
index 00000000000..ca89c943376
--- /dev/null
+++ b/llvm/test/LTO/X86/codemodel-1.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-objdump -d %t.s.0 | FileCheck %s --check-prefix=CHECK-SMALL
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-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 1}
+
+@data = internal constant [0 x i32] []
+
+define i32* @_start() nounwind readonly {
+entry:
+; CHECK-SMALL-LABEL: _start:
+; CHECK-SMALL: leaq (%rip), %rax
+ ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
+}
diff --git a/llvm/test/LTO/X86/codemodel-2.ll b/llvm/test/LTO/X86/codemodel-2.ll
new file mode 100644
index 00000000000..408c02a9ecf
--- /dev/null
+++ b/llvm/test/LTO/X86/codemodel-2.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-lto2 run -r %t.o,_start,px %t.o -o %t.s
+; RUN: llvm-objdump -d %t.s.0 | FileCheck %s --check-prefix=CHECK-LARGE
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-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* @_start() nounwind readonly {
+entry:
+; CHECK-LARGE-LABEL: _start:
+; CHECK-LARGE: movabsq $0, %rax
+ ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
+}
diff --git a/llvm/test/LTO/X86/codemodel-3.ll b/llvm/test/LTO/X86/codemodel-3.ll
new file mode 100644
index 00000000000..987d37d22c1
--- /dev/null
+++ b/llvm/test/LTO/X86/codemodel-3.ll
@@ -0,0 +1,20 @@
+; RUN: llvm-as %s -o %t0.o
+; RUN: llvm-as < %p/Inputs/codemodel-3.ll > %t1.o
+; RUN: not llvm-lto2 run -r %t0.o,_start,px -r %t1.o,bar,px %t0.o %t1.o -o %t2.s 2>&1 | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-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* @_start() nounwind readonly {
+entry:
+ ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
+}
+
+; CHECK: 'Code Model': IDs have conflicting values
OpenPOWER on IntegriCloud