Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Move to legalization in the JS backend (fastcomp) #126

Merged
merged 5 commits into from
Oct 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/Target/JSBackend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ add_dependencies(LLVMJSBackendCodeGen intrinsics_gen)

add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)
add_subdirectory(NaCl)
162 changes: 146 additions & 16 deletions lib/Target/JSBackend/JSBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/NaCl.h"
#include "llvm/Transforms/Scalar.h"
#include <algorithm>
#include <cstdio>
#include <map>
Expand Down Expand Up @@ -113,6 +115,27 @@ Relocatable("emscripten-relocatable",
cl::desc("Whether to emit relocatable code (see emscripten RELOCATABLE option)"),
cl::init(false));

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));

static cl::opt<bool>
EnableEmCxxExceptions("enable-emscripten-cxx-exceptions",
cl::desc("Enables C++ exceptions in emscripten"),
cl::init(false));

static cl::opt<bool>
EnableEmAsyncify("emscripten-asyncify",
cl::desc("Enable asyncify transformation (see emscripten ASYNCIFY option)"),
cl::init(false));

static cl::opt<bool>
NoExitRuntime("emscripten-no-exit-runtime",
cl::desc("Generate code which assumes the runtime is never exited (so atexit etc. is unneeded; see emscripten NO_EXIT_RUNTIME setting)"),
cl::init(false));


extern "C" void LLVMInitializeJSBackendTarget() {
// Register the target.
Expand Down Expand Up @@ -541,11 +564,11 @@ namespace {
/// @return The index to the heap HeapName for the memory access.
std::string getHeapNameAndIndex(const Value *Ptr, const char **HeapName);

// Like getHeapNameAndIndex(), but uses the given memory operation size instead of the one from Ptr.
std::string getHeapNameAndIndex(const Value *Ptr, const char **HeapName, unsigned Bytes);
// Like getHeapNameAndIndex(), but uses the given memory operation size and whether it is an Integer instead of the type of Ptr.
std::string getHeapNameAndIndex(const Value *Ptr, const char **HeapName, unsigned Bytes, bool Integer);

/// Like getHeapNameAndIndex(), but for global variables only.
std::string getHeapNameAndIndexToGlobal(const GlobalVariable *GV, const char **HeapName);
std::string getHeapNameAndIndexToGlobal(const GlobalVariable *GV, unsigned Bytes, bool Integer, const char **HeapName);

/// Like getHeapNameAndIndex(), but for pointers represented in string expression form.
static std::string getHeapNameAndIndexToPtr(const std::string& Ptr, unsigned Bytes, bool Integer, const char **HeapName);
Expand Down Expand Up @@ -959,12 +982,10 @@ static inline const char *getHeapShiftStr(int Bytes)
}
}

std::string JSWriter::getHeapNameAndIndexToGlobal(const GlobalVariable *GV, const char **HeapName)
std::string JSWriter::getHeapNameAndIndexToGlobal(const GlobalVariable *GV, unsigned Bytes, bool Integer, const char **HeapName)
{
Type *t = cast<PointerType>(GV->getType())->getElementType();
unsigned Bytes = DL->getTypeAllocSize(t);
unsigned Addr = getGlobalAddress(GV->getName().str());
*HeapName = getHeapName(Bytes, t->isIntegerTy() || t->isPointerTy());
*HeapName = getHeapName(Bytes, Integer);
if (!Relocatable) {
return utostr(Addr >> getHeapShift(Bytes));
} else {
Expand All @@ -978,22 +999,21 @@ std::string JSWriter::getHeapNameAndIndexToPtr(const std::string& Ptr, unsigned
return Ptr + getHeapShiftStr(Bytes);
}

std::string JSWriter::getHeapNameAndIndex(const Value *Ptr, const char **HeapName, unsigned Bytes)
std::string JSWriter::getHeapNameAndIndex(const Value *Ptr, const char **HeapName, unsigned Bytes, bool Integer)
{
Type *t = cast<PointerType>(Ptr->getType())->getElementType();

if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
return getHeapNameAndIndexToGlobal(GV, HeapName);
const GlobalVariable *GV;
if ((GV = dyn_cast<GlobalVariable>(Ptr->stripPointerCasts())) && GV->hasInitializer()) {
// Note that we use the type of the pointer, as it might be a bitcast of the underlying global. We need the right type.
return getHeapNameAndIndexToGlobal(GV, Bytes, Integer, HeapName);
} else {
return getHeapNameAndIndexToPtr(getValueAsStr(Ptr), Bytes, t->isIntegerTy() || t->isPointerTy(), HeapName);
return getHeapNameAndIndexToPtr(getValueAsStr(Ptr), Bytes, Integer, HeapName);
}
}

std::string JSWriter::getHeapNameAndIndex(const Value *Ptr, const char **HeapName)
{
Type *t = cast<PointerType>(Ptr->getType())->getElementType();
unsigned Bytes = DL->getTypeAllocSize(t);
return getHeapNameAndIndex(Ptr, HeapName, Bytes);
return getHeapNameAndIndex(Ptr, HeapName, DL->getTypeAllocSize(t), t->isIntegerTy() || t->isPointerTy());
}

static const char *heapNameToAtomicTypeName(const char *HeapName)
Expand Down Expand Up @@ -1268,7 +1288,7 @@ std::string JSWriter::getHeapAccess(const std::string& Name, unsigned Bytes, boo

std::string JSWriter::getShiftedPtr(const Value *Ptr, unsigned Bytes) {
const char *HeapName = 0; // unused
return getHeapNameAndIndex(Ptr, &HeapName, Bytes);
return getHeapNameAndIndex(Ptr, &HeapName, Bytes, true /* Integer; doesn't matter */);
}

std::string JSWriter::getPtrUse(const Value* Ptr) {
Expand Down Expand Up @@ -3609,6 +3629,116 @@ bool JSTargetMachine::addPassesToEmitFile(
assert(FileType == TargetMachine::CGFT_AssemblyFile);

PM.add(createCheckTriplePass());

if (NoExitRuntime) {
PM.add(createNoExitRuntimePass());
// removing atexits opens up globalopt/globaldce opportunities
PM.add(createGlobalOptimizerPass());
PM.add(createGlobalDCEPass());
}

// PNaCl legalization
{
PM.add(createStripDanglingDISubprogramsPass());
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 if (EnableEmCxxExceptions) {
PM.add(createLowerEmExceptionsPass());
} else {
// LowerInvoke prevents use of C++ exception handling by removing
// references to BasicBlocks which handle exceptions.
PM.add(createLowerInvokePass());
}
// Run CFG simplification passes for a few reasons:
// (1) Landingpad blocks can be made unreachable by LowerInvoke
// when EnableSjLjEH is not enabled, so clean those up to ensure
// there are no landingpad instructions in the stable ABI.
// (2) Unreachable blocks can have strange properties like self-referencing
// instructions, so remove them.
PM.add(createCFGSimplificationPass());

PM.add(createLowerEmSetjmpPass());

// Expand out computed gotos (indirectbr and blockaddresses) into switches.
PM.add(createExpandIndirectBrPass());

// ExpandStructRegs must be run after ExpandVarArgs so that struct-typed
// "va_arg" instructions have been removed.
PM.add(createExpandVarArgsPass());

// Convert struct reg function params to struct* byval. This needs to be
// before ExpandStructRegs so it has a chance to rewrite aggregates from
// function arguments and returns into something ExpandStructRegs can expand.
PM.add(createSimplifyStructRegSignaturesPass());

// TODO(mtrofin) Remove the following and only run it as a post-opt pass once
// the following bug is fixed.
// https://code.google.com/p/nativeclient/issues/detail?id=3857
PM.add(createExpandStructRegsPass());

PM.add(createExpandCtorsPass());

if (EnableEmAsyncify)
PM.add(createLowerEmAsyncifyPass());

// ExpandStructRegs must be run after ExpandArithWithOverflow to expand out
// the insertvalue instructions that ExpandArithWithOverflow introduces.
PM.add(createExpandArithWithOverflowPass());

// 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());

PM.add(createPromoteI1OpsPass());

// We should not place arbitrary passes after ExpandConstantExpr
// because they might reintroduce ConstantExprs.
PM.add(createExpandConstantExprPass());
// 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());

// 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());

// 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());
// Rewrite atomic and volatile instructions with intrinsic calls.
PM.add(createRewriteAtomicsPass());

PM.add(createSimplifyAllocasPass());

// 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.
PM.add(createExpandStructRegsPass());

// Eliminate simple dead code that the post-opt passes could have created.
PM.add(createDeadCodeEliminationPass());
}
// end PNaCl legalization

PM.add(createExpandInsertExtractElementPass());
PM.add(createExpandI64Pass());

Expand Down
4 changes: 2 additions & 2 deletions lib/Target/JSBackend/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;

[common]
subdirectories = MCTargetDesc TargetInfo
subdirectories = MCTargetDesc NaCl TargetInfo

[component_0]
type = TargetGroup
Expand All @@ -27,5 +27,5 @@ parent = Target
type = Library
name = JSBackendCodeGen
parent = JSBackend
required_libraries = Analysis CodeGen Core JSBackendInfo JSBackendDesc NaClTransforms Support Target
required_libraries = Analysis CodeGen Core JSBackendInfo JSBackendDesc PNaClTransforms Support Target
add_to_library_groups = JSBackend
2 changes: 1 addition & 1 deletion lib/Target/JSBackend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

LEVEL = ../../..
LIBRARYNAME = LLVMJSBackendCodeGen
DIRS = MCTargetDesc TargetInfo
DIRS = MCTargetDesc NaCl TargetInfo

include $(LEVEL)/Makefile.common

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
add_llvm_library(LLVMNaClTransforms
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )

add_llvm_library(LLVMPNaClTransforms
AddPNaClExternalDecls.cpp
BackendCanonicalize.cpp
CanonicalizeMemIntrinsics.cpp
Expand Down Expand Up @@ -27,7 +29,6 @@ add_llvm_library(LLVMNaClTransforms
InsertDivideCheck.cpp
InternalizeUsedGlobals.cpp
NormalizeAlignment.cpp
PNaClABISimplify.cpp
PNaClSjLjEH.cpp
PromoteI1Ops.cpp
PromoteIntegers.cpp
Expand All @@ -51,4 +52,4 @@ add_llvm_library(LLVMNaClTransforms
# Emscripten files end.
)

add_dependencies(LLVMNaClTransforms intrinsics_gen)
add_dependencies(LLVMPNaClTransforms intrinsics_gen)
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ static bool isEmscriptenJSArgsFunc(Module *M, StringRef Name) {
}

static bool ExpandVarArgFunc(Module *M, Function *Func) {
if (Func->isDeclaration() && Func->use_empty())
return false; // No point in doing any work.

if (isEmscriptenJSArgsFunc(M, Func->getName()))
return false;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
;===- ./lib/Transforms/NaCl/LLVMBuild.txt ----------------------*- Conf -*--===;
;===- ./lib/Target/JSBackend/NaCl/LLVMBuild.txt ---------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;===-----------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
;===-----------------------------------------------------------------------===;

[component_0]
type = Library
name = NaClTransforms
parent = Transforms
library_name = NaClTransforms
name = PNaClTransforms
parent = JSBackend
required_libraries = Analysis Core Support IPO Scalar TransformUtils
add_to_library_groups = JSBackend
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
##===- lib/Transforms/NaCl/Makefile-------------------------*- Makefile -*-===##
##===- lib/Target/JSBackend/NaCl/Makefile-------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LEVEL = ../../..
LIBRARYNAME = LLVMNaClTransforms
BUILD_ARCHIVE = 1
LEVEL = ../../../..
LIBRARYNAME = LLVMPNaClTransforms

include $(LEVEL)/Makefile.common

1 change: 0 additions & 1 deletion lib/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ add_subdirectory(IPO)
add_subdirectory(Vectorize)
add_subdirectory(Hello)
add_subdirectory(ObjCARC)
add_subdirectory(NaCl)
2 changes: 1 addition & 1 deletion lib/Transforms/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;

[common]
subdirectories = IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC NaCl
subdirectories = IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC

[component_0]
type = Group
Expand Down
2 changes: 1 addition & 1 deletion lib/Transforms/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##

LEVEL = ../..
PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello ObjCARC NaCl
PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello ObjCARC

include $(LEVEL)/Makefile.config

Expand Down
Loading