| Index: lib/Transforms/NaCl/PNaClABISimplify.cpp
|
| diff --git a/lib/Transforms/NaCl/PNaClABISimplify.cpp b/lib/Transforms/NaCl/PNaClABISimplify.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..99e3796abeee99a39341afedddf6ec7660e41bb4
|
| --- /dev/null
|
| +++ b/lib/Transforms/NaCl/PNaClABISimplify.cpp
|
| @@ -0,0 +1,174 @@
|
| +//===-- 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;
|
| +
|
| +static cl::opt<bool>
|
| +EnableSjLjEH("enable-pnacl-sjlj-eh",
|
| + cl::desc("Enable use of SJLJ-based C++ exception handling "
|
| + "as part of the pnacl-abi-simplify passes"),
|
| + cl::init(false));
|
| +
|
| +void llvm::PNaClABISimplifyAddPreOptPasses(PassManagerBase &PM) {
|
| + if (EnableSjLjEH) {
|
| + // This comes before ExpandTls because it introduces references to
|
| + // a TLS variable, __pnacl_eh_stack. This comes before
|
| + // InternalizePass because it assumes various variables (including
|
| + // __pnacl_eh_stack) have not been internalized yet.
|
| + PM.add(createPNaClSjLjEHPass());
|
| + } else {
|
| + // LowerInvoke prevents use of C++ exception handling by removing
|
| + // references to BasicBlocks which handle exceptions.
|
| + PM.add(createLowerInvokePass());
|
| + // Remove landingpad blocks made unreachable by LowerInvoke.
|
| + PM.add(createCFGSimplificationPass());
|
| + }
|
| +
|
| + // Internalize all symbols in the module except the entry point. A PNaCl
|
| + // pexe is only allowed to export "_start", whereas a PNaCl PSO is only
|
| + // allowed to export "__pnacl_pso_root".
|
| + const char *SymbolsToPreserve[] = { "_start", "__pnacl_pso_root" };
|
| + PM.add(createInternalizePass(SymbolsToPreserve));
|
| +
|
| + // Expand out computed gotos (indirectbr and blockaddresses) into switches.
|
| + PM.add(createExpandIndirectBrPass());
|
| +
|
| + // LowerExpect converts Intrinsic::expect into branch weights,
|
| + // which can then be removed after BlockPlacement.
|
| + PM.add(createLowerExpectIntrinsicPass());
|
| + // Rewrite unsupported intrinsics to simpler and portable constructs.
|
| + PM.add(createRewriteLLVMIntrinsicsPass());
|
| +
|
| + // Expand out some uses of struct types.
|
| + PM.add(createExpandVarArgsPass());
|
| + PM.add(createExpandArithWithOverflowPass());
|
| + // ExpandStructRegs must be run after ExpandArithWithOverflow to
|
| + // expand out the insertvalue instructions that
|
| + // ExpandArithWithOverflow introduces. ExpandStructRegs must be run
|
| + // after ExpandVarArgs so that struct-typed "va_arg" instructions
|
| + // have been removed.
|
| + PM.add(createExpandStructRegsPass());
|
| +
|
| + 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());
|
| +}
|
| +
|
| +void llvm::PNaClABISimplifyAddPostOptPasses(PassManagerBase &PM) {
|
| + PM.add(createRewritePNaClLibraryCallsPass());
|
| +
|
| + // 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 ExpandSmallArguments after optimization passes because
|
| + // some optimizations undo its changes. Note that
|
| + // ExpandSmallArguments requires that ExpandVarArgs has already been
|
| + // run.
|
| + PM.add(createExpandSmallArgumentsPass());
|
| +
|
| + PM.add(createPromoteI1OpsPass());
|
| +
|
| + // Vector simplifications.
|
| + //
|
| + // The following pass relies on ConstantInsertExtractElementIndex running
|
| + // after it, and it must run before GlobalizeConstantVectors because the mask
|
| + // argument of shufflevector must be a constant (the pass would otherwise
|
| + // violate this requirement).
|
| + PM.add(createExpandShuffleVectorPass());
|
| + // We should not place arbitrary passes after ExpandConstantExpr
|
| + // because they might reintroduce ConstantExprs.
|
| + PM.add(createExpandConstantExprPass());
|
| + // GlobalizeConstantVectors does not handle nested ConstantExprs, so we
|
| + // run ExpandConstantExpr first.
|
| + PM.add(createGlobalizeConstantVectorsPass());
|
| + // The following pass inserts GEPs, it must precede ExpandGetElementPtr. It
|
| + // also creates vector loads and stores, the subsequent pass cleans them up to
|
| + // fix their alignment.
|
| + PM.add(createConstantInsertExtractElementIndexPass());
|
| + PM.add(createFixVectorLoadStoreAlignmentPass());
|
| +
|
| + // Optimization passes and ExpandByVal introduce
|
| + // memset/memcpy/memmove intrinsics with a 64-bit size argument.
|
| + // This pass converts those arguments to 32-bit.
|
| + PM.add(createCanonicalizeMemIntrinsicsPass());
|
| +
|
| + // We place StripMetadata after optimization passes because
|
| + // optimizations depend on the metadata.
|
| + PM.add(createStripMetadataPass());
|
| +
|
| + // ConstantMerge cleans up after passes such as GlobalizeConstantVectors. It
|
| + // must run before the FlattenGlobals pass because FlattenGlobals loses
|
| + // information that otherwise helps ConstantMerge do a good job.
|
| + PM.add(createConstantMergePass());
|
| + // FlattenGlobals introduces ConstantExpr bitcasts of globals which
|
| + // are expanded out later. ReplacePtrsWithInts also creates some
|
| + // ConstantExprs, and it locally creates an ExpandConstantExprPass
|
| + // to clean both of these up.
|
| + PM.add(createFlattenGlobalsPass());
|
| +
|
| + // The type legalization passes (ExpandLargeIntegers and PromoteIntegers) do
|
| + // not handle constexprs and create GEPs, so they go between those passes.
|
| + PM.add(createExpandLargeIntegersPass());
|
| + PM.add(createPromoteIntegersPass());
|
| + // ExpandGetElementPtr must follow ExpandConstantExpr to expand the
|
| + // getelementptr instructions it creates.
|
| + PM.add(createExpandGetElementPtrPass());
|
| + // Rewrite atomic and volatile instructions with intrinsic calls.
|
| + PM.add(createRewriteAtomicsPass());
|
| + // Remove ``asm("":::"memory")``. This must occur after rewriting
|
| + // atomics: a ``fence seq_cst`` surrounded by ``asm("":::"memory")``
|
| + // has special meaning and is translated differently.
|
| + PM.add(createRemoveAsmMemoryPass());
|
| +
|
| + PM.add(createSimplifyAllocasPass());
|
| +
|
| + // ReplacePtrsWithInts assumes that getelementptr instructions and
|
| + // ConstantExprs have already been expanded out.
|
| + PM.add(createReplacePtrsWithIntsPass());
|
| +
|
| + // The atomic cmpxchg instruction returns a struct, and is rewritten to an
|
| + // intrinsic as a post-opt pass, we therefore need to expand struct regs one
|
| + // last time.
|
| + PM.add(createExpandStructRegsPass());
|
| +
|
| + // We place StripAttributes after optimization passes because many
|
| + // analyses add attributes to reflect their results.
|
| + // StripAttributes must come after ExpandByVal and
|
| + // ExpandSmallArguments.
|
| + PM.add(createStripAttributesPass());
|
| +
|
| + // Strip dead prototytes to appease the intrinsic ABI checks.
|
| + // ExpandVarArgs leaves around vararg intrinsics, and
|
| + // ReplacePtrsWithInts leaves the lifetime.start/end intrinsics.
|
| + PM.add(createStripDeadPrototypesPass());
|
| +
|
| + // Eliminate simple dead code that the post-opt passes could have
|
| + // created.
|
| + PM.add(createDeadInstEliminationPass());
|
| + PM.add(createDeadCodeEliminationPass());
|
| +}
|
|
|