Add Position-independent Code model Module API.
authorJustin Hibbits <jrh29@alumni.cwru.edu>
Fri, 7 Nov 2014 04:46:10 +0000 (04:46 +0000)
committerJustin Hibbits <jrh29@alumni.cwru.edu>
Fri, 7 Nov 2014 04:46:10 +0000 (04:46 +0000)
Summary:
This makes PIC levels a Module flag attribute, which can be queried by the
backend.  The flag is named `PIC Level`, and can have a value of:

  0 - Backend-default
  1 - Small-model (-fpic)
  2 - Large-model (-fPIC)

These match the `-pic-level' command line argument for clang, and the value of the
preprocessor macro `__PIC__'.

Test Plan:
New flags tests specific for the 'PIC Level' module flag.
Tests to be added as part of a future commit for PowerPC, which will use this new API.

Reviewers: rafael, echristo

Reviewed By: rafael, echristo

Subscribers: rafael, llvm-commits

Differential Revision: http://reviews.llvm.org/D5882

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221510 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/Module.h
include/llvm/Support/CodeGen.h
lib/IR/Module.cpp
test/Linker/Inputs/module-flags-pic-1-b.ll [new file with mode: 0644]
test/Linker/Inputs/module-flags-pic-2-b.ll [new file with mode: 0644]
test/Linker/module-flags-pic-1-a.ll [new file with mode: 0644]
test/Linker/module-flags-pic-2-a.ll [new file with mode: 0644]

index 8bf67a3efea4819aa9f944dcafa276577f8b39f2..23bdde56c7170b17ea605f7ad0e1de2fdec5c620 100644 (file)
@@ -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.
index 240eba6c8a4195a000891d9c4d71028f0a549e9d..243f2dd7498c3b55662b7fcf27a9b3e761d41841 100644 (file)
@@ -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 {
index 35d28481fcbb8342a4b599a14eb98fe99f4c53b8..bc50db3f56c7c3c937de5589fc887136a408b270 100644 (file)
@@ -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/test/Linker/Inputs/module-flags-pic-1-b.ll b/test/Linker/Inputs/module-flags-pic-1-b.ll
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/test/Linker/Inputs/module-flags-pic-2-b.ll b/test/Linker/Inputs/module-flags-pic-2-b.ll
new file mode 100644 (file)
index 0000000..228e04a
--- /dev/null
@@ -0,0 +1,3 @@
+!0 = metadata !{ i32 1, metadata !"PIC Level", i32 2 }
+
+!llvm.module.flags = !{!0}
diff --git a/test/Linker/module-flags-pic-1-a.ll b/test/Linker/module-flags-pic-1-a.ll
new file mode 100644 (file)
index 0000000..bc4da95
--- /dev/null
@@ -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/test/Linker/module-flags-pic-2-a.ll b/test/Linker/module-flags-pic-2-a.ll
new file mode 100644 (file)
index 0000000..3ff9c8f
--- /dev/null
@@ -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