aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-05-24 17:05:15 -0700
committerMark Seaborn <mseaborn@chromium.org>2013-05-24 17:05:15 -0700
commit33f698a2d1a30e31fb494922e3e6df8e643dc7b5 (patch)
treeda30ffef663e43c2a5b82cc9f2bf8e06e81dba03
parentde078f629ea70df5987a28390c1d3a0da5c844d5 (diff)
PNaCl: Add "-pnacl-abi-simplify-{pre,post}opt" meta-passes to "opt"
These meta-passes will be used to replace the pass lists that are currently in the pnacl-ld.py driver script in the NaCl repo. I've moved the comments across from pnacl-ld.py and added a couple more comments for ExpandByVal and StripMetadata. Fix the declaration of createResolveAliasesPass(). BUG=https://code.google.com/p/nativeclient/issues/detail?id=3435 TEST=new *.ll tests + tested with change to pnacl-ld.py Review URL: https://codereview.chromium.org/15669002
-rw-r--r--include/llvm/Transforms/NaCl.h4
-rw-r--r--lib/Transforms/NaCl/CMakeLists.txt1
-rw-r--r--lib/Transforms/NaCl/GlobalCleanup.cpp2
-rw-r--r--lib/Transforms/NaCl/PNaClABISimplify.cpp65
-rw-r--r--test/Transforms/NaCl/pnacl-abi-simplify-postopt.ll16
-rw-r--r--test/Transforms/NaCl/pnacl-abi-simplify-preopt.ll38
-rw-r--r--tools/opt/opt.cpp35
7 files changed, 160 insertions, 1 deletions
diff --git a/include/llvm/Transforms/NaCl.h b/include/llvm/Transforms/NaCl.h
index af1dee2ebe..3b9ce35dc8 100644
--- a/include/llvm/Transforms/NaCl.h
+++ b/include/llvm/Transforms/NaCl.h
@@ -16,6 +16,7 @@ class BasicBlockPass;
class FunctionPass;
class Instruction;
class ModulePass;
+class PassManager;
class Use;
class Value;
@@ -36,6 +37,9 @@ ModulePass *createRewritePNaClLibraryCallsPass();
ModulePass *createStripMetadataPass();
FunctionPass *createInsertDivideCheckPass();
+void PNaClABISimplifyAddPreOptPasses(PassManager &PM);
+void PNaClABISimplifyAddPostOptPasses(PassManager &PM);
+
Instruction *PhiSafeInsertPt(Use *U);
void PhiSafeReplaceUses(Use *U, Value *NewVal);
diff --git a/lib/Transforms/NaCl/CMakeLists.txt b/lib/Transforms/NaCl/CMakeLists.txt
index 1fabdbc1db..a98d929f83 100644
--- a/lib/Transforms/NaCl/CMakeLists.txt
+++ b/lib/Transforms/NaCl/CMakeLists.txt
@@ -11,6 +11,7 @@ add_llvm_library(LLVMNaClTransforms
InsertDivideCheck.cpp
FlattenGlobals.cpp
GlobalCleanup.cpp
+ PNaClABISimplify.cpp
PromoteIntegers.cpp
ReplacePtrsWithInts.cpp
RewritePNaClLibraryCalls.cpp
diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp
index 00e15b39a5..55886f8f7d 100644
--- a/lib/Transforms/NaCl/GlobalCleanup.cpp
+++ b/lib/Transforms/NaCl/GlobalCleanup.cpp
@@ -113,6 +113,6 @@ bool ResolveAliases::runOnModule(Module &M) {
return Modified;
}
-ModulePass *createResolveAliasesPass() {
+ModulePass *llvm::createResolveAliasesPass() {
return new ResolveAliases();
}
diff --git a/lib/Transforms/NaCl/PNaClABISimplify.cpp b/lib/Transforms/NaCl/PNaClABISimplify.cpp
new file mode 100644
index 0000000000..9d7713139a
--- /dev/null
+++ b/lib/Transforms/NaCl/PNaClABISimplify.cpp
@@ -0,0 +1,65 @@
+//===-- PNaClABISimplify.cpp - Lists PNaCl ABI simplification passes ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the meta-passes "-pnacl-abi-simplify-preopt"
+// and "-pnacl-abi-simplify-postopt". It lists their constituent
+// passes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/NaCl.h"
+#include "llvm/PassManager.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/NaCl.h"
+#include "llvm/Transforms/Scalar.h"
+
+using namespace llvm;
+
+void llvm::PNaClABISimplifyAddPreOptPasses(PassManager &PM) {
+ // LowerInvoke prevents use of C++ exception handling, which is not
+ // yet supported in the PNaCl ABI.
+ PM.add(createLowerInvokePass());
+ // Remove landingpad blocks made unreachable by LowerInvoke.
+ PM.add(createCFGSimplificationPass());
+
+ PM.add(createExpandVarArgsPass());
+ PM.add(createExpandCtorsPass());
+ PM.add(createResolveAliasesPass());
+ PM.add(createExpandTlsPass());
+ // GlobalCleanup needs to run after ExpandTls because
+ // __tls_template_start etc. are extern_weak before expansion
+ PM.add(createGlobalCleanupPass());
+ // Strip dead prototytes to appease the intrinsic ABI checks
+ // (ExpandVarArgs leaves around var-arg intrinsics).
+ PM.add(createStripDeadPrototypesPass());
+}
+
+void llvm::PNaClABISimplifyAddPostOptPasses(PassManager &PM) {
+ // We place ExpandByVal after optimization passes because some byval
+ // arguments can be expanded away by the ArgPromotion pass. Leaving
+ // in "byval" during optimization also allows some dead stores to be
+ // eliminated, because "byval" is a stronger constraint than what
+ // ExpandByVal expands it to.
+ PM.add(createExpandByValPass());
+
+ // We place StripMetadata after optimization passes because
+ // optimizations depend on the metadata.
+ PM.add(createStripMetadataPass());
+
+ // FlattenGlobals introduces ConstantExpr bitcasts of globals which
+ // are expanded out later.
+ PM.add(createFlattenGlobalsPass());
+
+ // We should not place arbitrary passes after ExpandConstantExpr
+ // because they might reintroduce ConstantExprs. However,
+ // ExpandGetElementPtr must follow ExpandConstantExpr to expand the
+ // getelementptr instructions it creates.
+ PM.add(createExpandConstantExprPass());
+ PM.add(createExpandGetElementPtrPass());
+}
diff --git a/test/Transforms/NaCl/pnacl-abi-simplify-postopt.ll b/test/Transforms/NaCl/pnacl-abi-simplify-postopt.ll
new file mode 100644
index 0000000000..a1ea6dc0ca
--- /dev/null
+++ b/test/Transforms/NaCl/pnacl-abi-simplify-postopt.ll
@@ -0,0 +1,16 @@
+; RUN: opt %s -pnacl-abi-simplify-postopt -S | FileCheck %s
+
+; "-pnacl-abi-simplify-postopt" runs various passes which are tested
+; thoroughly in other *.ll files. This file is a smoke test to check
+; that the passes work together OK.
+
+
+@var = global i32 256
+; CHECK: @var = global [4 x i8]
+
+define i16 @read_var() {
+ %val = load i16* bitcast (i32* @var to i16*)
+ ret i16 %val
+}
+; CHECK: = bitcast [4 x i8]* @var
+; CHECK-NEXT: load i16*
diff --git a/test/Transforms/NaCl/pnacl-abi-simplify-preopt.ll b/test/Transforms/NaCl/pnacl-abi-simplify-preopt.ll
new file mode 100644
index 0000000000..1cf7377559
--- /dev/null
+++ b/test/Transforms/NaCl/pnacl-abi-simplify-preopt.ll
@@ -0,0 +1,38 @@
+; RUN: opt %s -pnacl-abi-simplify-preopt -S | FileCheck %s
+
+; "-pnacl-abi-simplify-preopt" runs various passes which are tested
+; thoroughly in other *.ll files. This file is a smoke test to check
+; that "-pnacl-abi-simplify-preopt" runs what it's supposed to run.
+
+declare void @ext_func()
+
+
+define void @invoke_func() {
+ invoke void @ext_func() to label %cont unwind label %lpad
+cont:
+ ret void
+lpad:
+ %lp = landingpad { i8*, i32 } personality i8* null cleanup
+ ret void
+}
+; CHECK-NOT: invoke void @ext_func()
+; CHECK-NOT: landingpad
+
+
+define void @varargs_func(...) {
+ ret void
+}
+; CHECK-NOT: @varargs_func(...)
+
+
+@llvm.global_ctors = appending global [0 x { i32, void ()* }] zeroinitializer
+; CHECK-NOT: @llvm.global_ctors
+
+@tls_var = thread_local global i32 0
+; CHECK-NOT: thread_local
+
+@alias = alias i32* @tls_var
+; CHECK-NOT: @alias
+
+@weak_ref = extern_weak global i8*
+; CHECK-NOT: extern_weak
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 3179e17733..35e18d02ad 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -45,6 +45,7 @@
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/NaCl.h" // @LOCALMOD
#include <algorithm>
#include <memory>
using namespace llvm;
@@ -127,6 +128,18 @@ static cl::opt<bool>
OptLevelO3("O3",
cl::desc("Optimization level 3. Similar to clang -O3"));
+// @LOCALMOD-BEGIN
+static cl::opt<bool>
+PNaClABISimplifyPreOpt(
+ "pnacl-abi-simplify-preopt",
+ cl::desc("PNaCl ABI simplifications for before optimizations"));
+
+static cl::opt<bool>
+PNaClABISimplifyPostOpt(
+ "pnacl-abi-simplify-postopt",
+ cl::desc("PNaCl ABI simplifications for after optimizations"));
+// @LOCALMOD-END
+
static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));
@@ -760,6 +773,20 @@ int main(int argc, char **argv) {
OptLevelO3 = false;
}
+ // @LOCALMOD-BEGIN
+ if (PNaClABISimplifyPreOpt &&
+ PNaClABISimplifyPreOpt.getPosition() < PassList.getPosition(i)) {
+ PNaClABISimplifyAddPreOptPasses(Passes);
+ PNaClABISimplifyPreOpt = false;
+ }
+
+ if (PNaClABISimplifyPostOpt &&
+ PNaClABISimplifyPostOpt.getPosition() < PassList.getPosition(i)) {
+ PNaClABISimplifyAddPostOptPasses(Passes);
+ PNaClABISimplifyPostOpt = false;
+ }
+ // @LOCALMOD-END
+
const PassInfo *PassInf = PassList[i];
Pass *P = 0;
if (PassInf->getNormalCtor())
@@ -832,6 +859,14 @@ int main(int argc, char **argv) {
FPasses->doFinalization();
}
+ // @LOCALMOD-BEGIN
+ if (PNaClABISimplifyPreOpt)
+ PNaClABISimplifyAddPreOptPasses(Passes);
+
+ if (PNaClABISimplifyPostOpt)
+ PNaClABISimplifyAddPostOptPasses(Passes);
+ // @LOCALMOD-END
+
// Check that the module is well formed on completion of optimization
if (!NoVerify && !VerifyEach)
Passes.add(createVerifierPass());