#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"
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
/// @{
#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"
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);
}
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,
--- /dev/null
+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)
--- /dev/null
+; 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)
+}
--- /dev/null
+; 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)
+}
--- /dev/null
+; 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