summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Module.h10
-rw-r--r--llvm/include/llvm/Support/CodeGen.h4
-rw-r--r--llvm/lib/IR/Module.cpp13
-rw-r--r--llvm/test/Linker/Inputs/module-flags-pic-1-b.ll1
-rw-r--r--llvm/test/Linker/Inputs/module-flags-pic-2-b.ll3
-rw-r--r--llvm/test/Linker/module-flags-pic-1-a.ll9
-rw-r--r--llvm/test/Linker/module-flags-pic-2-a.ll10
7 files changed, 50 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 8bf67a3efea..23bdde56c71 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -23,6 +23,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/DataTypes.h"
#include <system_error>
@@ -634,6 +635,15 @@ public:
unsigned getDwarfVersion() const;
/// @}
+/// @name Utility functions for querying and setting PIC level
+/// @{
+
+ /// \brief Returns the PIC level (small or large model)
+ PICLevel::Level getPICLevel() const;
+
+ /// \brief Set the PIC level (small or large model)
+ void setPICLevel(PICLevel::Level PL);
+/// @}
};
/// An raw_ostream inserter for modules.
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h
index 240eba6c8a4..243f2dd7498 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -30,6 +30,10 @@ namespace llvm {
enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
}
+ namespace PICLevel {
+ enum Level { Default=0, Small=1, Large=2 };
+ }
+
// TLS models.
namespace TLSModel {
enum Model {
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 35d28481fcb..bc50db3f56c 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -459,3 +459,16 @@ Comdat *Module::getOrInsertComdat(StringRef Name) {
Entry.second.Name = &Entry;
return &Entry.second;
}
+
+PICLevel::Level Module::getPICLevel() const {
+ Value *Val = getModuleFlag("PIC Level");
+
+ if (Val == NULL)
+ return PICLevel::Default;
+
+ return static_cast<PICLevel::Level>(cast<ConstantInt>(Val)->getZExtValue());
+}
+
+void Module::setPICLevel(PICLevel::Level PL) {
+ addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL);
+}
diff --git a/llvm/test/Linker/Inputs/module-flags-pic-1-b.ll b/llvm/test/Linker/Inputs/module-flags-pic-1-b.ll
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/llvm/test/Linker/Inputs/module-flags-pic-1-b.ll
@@ -0,0 +1 @@
+
diff --git a/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll b/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll
new file mode 100644
index 00000000000..228e04ab4da
--- /dev/null
+++ b/llvm/test/Linker/Inputs/module-flags-pic-2-b.ll
@@ -0,0 +1,3 @@
+!0 = metadata !{ i32 1, metadata !"PIC Level", i32 2 }
+
+!llvm.module.flags = !{!0}
diff --git a/llvm/test/Linker/module-flags-pic-1-a.ll b/llvm/test/Linker/module-flags-pic-1-a.ll
new file mode 100644
index 00000000000..bc4da9541ac
--- /dev/null
+++ b/llvm/test/Linker/module-flags-pic-1-a.ll
@@ -0,0 +1,9 @@
+; RUN: llvm-link %s %p/Inputs/module-flags-pic-1-b.ll -S -o - | FileCheck %s
+
+; test linking modules with specified and default PIC levels
+
+!0 = metadata !{ i32 1, metadata !"PIC Level", i32 1 }
+
+!llvm.module.flags = !{!0}
+; CHECK: !llvm.module.flags = !{!0}
+; CHECK: !0 = metadata !{i32 1, metadata !"PIC Level", i32 1}
diff --git a/llvm/test/Linker/module-flags-pic-2-a.ll b/llvm/test/Linker/module-flags-pic-2-a.ll
new file mode 100644
index 00000000000..3ff9c8ffe83
--- /dev/null
+++ b/llvm/test/Linker/module-flags-pic-2-a.ll
@@ -0,0 +1,10 @@
+; RUN: not llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - 2> %t
+; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
+
+; test linking modules with two different PIC levels
+
+!0 = metadata !{ i32 1, metadata !"PIC Level", i32 1 }
+
+!llvm.module.flags = !{!0}
+
+; CHECK-ERRORS: ERROR: linking module flags 'PIC Level': IDs have conflicting values
OpenPOWER on IntegriCloud