From 3e03f7374169cd41547d75e62ac2ab8a103a913c Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 30 Aug 2016 20:03:33 -0700 Subject: [PATCH] Import of fastcomp commit 4105790f1549808c1f1daa5250b4ada5f41a5c02 This is a minimal import of the emscripten "fastcomp" LLVM patchset. All it contains is the target definitions necessary to create a TargetMachine with the correct data layout. With this rustc can emit LLVM IR that emcc will run through the PNaCl lagalizer and the JS backend to generate asm.js. --- CMakeLists.txt | 1 + include/llvm/ADT/Triple.h | 9 ++ lib/Support/Triple.cpp | 13 ++ lib/Target/JSBackend/CMakeLists.txt | 10 ++ lib/Target/JSBackend/JS.h | 24 ++++ lib/Target/JSBackend/JSBackend.cpp | 40 ++++++ lib/Target/JSBackend/JSTargetMachine.cpp | 48 +++++++ lib/Target/JSBackend/JSTargetMachine.h | 71 +++++++++++ .../JSBackend/JSTargetTransformInfo.cpp | 118 ++++++++++++++++++ lib/Target/JSBackend/JSTargetTransformInfo.h | 96 ++++++++++++++ lib/Target/JSBackend/LLVMBuild.txt | 31 +++++ .../JSBackend/MCTargetDesc/CMakeLists.txt | 6 + .../MCTargetDesc/JSBackendMCTargetDesc.cpp | 22 ++++ .../MCTargetDesc/JSBackendMCTargetDesc.h | 25 ++++ .../JSBackend/MCTargetDesc/LLVMBuild.txt | 24 ++++ .../JSBackend/TargetInfo/CMakeLists.txt | 5 + .../TargetInfo/JSBackendTargetInfo.cpp | 20 +++ lib/Target/JSBackend/TargetInfo/LLVMBuild.txt | 23 ++++ lib/Target/LLVMBuild.txt | 1 + lib/Transforms/IPO/ConstantMerge.cpp | 7 ++ .../InstCombine/InstCombineCompares.cpp | 5 + 21 files changed, 599 insertions(+) create mode 100644 lib/Target/JSBackend/CMakeLists.txt create mode 100644 lib/Target/JSBackend/JS.h create mode 100644 lib/Target/JSBackend/JSBackend.cpp create mode 100644 lib/Target/JSBackend/JSTargetMachine.cpp create mode 100644 lib/Target/JSBackend/JSTargetMachine.h create mode 100644 lib/Target/JSBackend/JSTargetTransformInfo.cpp create mode 100644 lib/Target/JSBackend/JSTargetTransformInfo.h create mode 100644 lib/Target/JSBackend/LLVMBuild.txt create mode 100644 lib/Target/JSBackend/MCTargetDesc/CMakeLists.txt create mode 100644 lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.cpp create mode 100644 lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.h create mode 100644 lib/Target/JSBackend/MCTargetDesc/LLVMBuild.txt create mode 100644 lib/Target/JSBackend/TargetInfo/CMakeLists.txt create mode 100644 lib/Target/JSBackend/TargetInfo/JSBackendTargetInfo.cpp create mode 100644 lib/Target/JSBackend/TargetInfo/LLVMBuild.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f1024242f516..0b4867f88530 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,7 @@ set(LLVM_ALL_TARGETS ARM BPF Hexagon + JSBackend # @LOCALMOD Mips MSP430 NVPTX diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index b98f8407d075..4f0805518228 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -78,6 +78,7 @@ class Triple { nvptx64, // NVPTX: 64-bit le32, // le32: generic little-endian 32-bit CPU (PNaCl) le64, // le64: generic little-endian 64-bit CPU (PNaCl) + asmjs, // asm.js JavaScript subset @LOCALMOD Emscripten amdil, // AMDIL amdil64, // AMDIL with 64-bit pointers hsail, // AMD HSAIL @@ -156,6 +157,7 @@ class Triple { Haiku, Minix, RTEMS, + Emscripten, // Emscripten JavaScript runtime @LOCALMOD Emscripten NaCl, // Native Client CNK, // BG/P Compute-Node Kernel Bitrig, @@ -531,6 +533,13 @@ class Triple { return getOS() == Triple::NaCl; } + // @LOCALMOD-START Emscripten + /// Tests whether the OS is Emscripten. + bool isOSEmscripten() const { + return getOS() == Triple::Emscripten; + } + // @LOCALMOD-END Emscripten + /// Tests whether the OS is Linux. bool isOSLinux() const { return getOS() == Triple::Linux; diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 2bac2a310670..35156b3df139 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -53,6 +53,7 @@ const char *Triple::getArchTypeName(ArchType Kind) { case nvptx64: return "nvptx64"; case le32: return "le32"; case le64: return "le64"; + case asmjs: return "asmjs"; // @LOCALMOD Emscripten case amdil: return "amdil"; case amdil64: return "amdil64"; case hsail: return "hsail"; @@ -121,6 +122,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case le32: return "le32"; case le64: return "le64"; + case asmjs: return "asmjs"; // @LOCALMOD Emscripten + case amdil: case amdil64: return "amdil"; @@ -180,6 +183,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case Haiku: return "haiku"; case Minix: return "minix"; case RTEMS: return "rtems"; + case Emscripten: return "emscripten"; // @LOCALMOD Emscripten case NaCl: return "nacl"; case CNK: return "cnk"; case Bitrig: return "bitrig"; @@ -273,6 +277,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("nvptx64", nvptx64) .Case("le32", le32) .Case("le64", le64) + .Case("asmjs", asmjs) // @LOCALMOD Emscripten .Case("amdil", amdil) .Case("amdil64", amdil64) .Case("hsail", hsail) @@ -384,6 +389,7 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("nvptx64", Triple::nvptx64) .Case("le32", Triple::le32) .Case("le64", Triple::le64) + .Case("asmjs", Triple::asmjs) // @LOCALMOD Emscripten .Case("amdil", Triple::amdil) .Case("amdil64", Triple::amdil64) .Case("hsail", Triple::hsail) @@ -450,6 +456,7 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("haiku", Triple::Haiku) .StartsWith("minix", Triple::Minix) .StartsWith("rtems", Triple::RTEMS) + .StartsWith("emscripten", Triple::Emscripten) // @LOCALMOD Emscripten .StartsWith("nacl", Triple::NaCl) .StartsWith("cnk", Triple::CNK) .StartsWith("bitrig", Triple::Bitrig) @@ -584,6 +591,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { case Triple::amdil: case Triple::amdil64: case Triple::armeb: + case Triple::asmjs: // @LOCALMOD Emscripten case Triple::avr: case Triple::bpfeb: case Triple::bpfel: @@ -1127,6 +1135,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::armeb: case llvm::Triple::hexagon: case llvm::Triple::le32: + case llvm::Triple::asmjs: // @LOCALMOD Emscripten case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::nvptx: @@ -1207,6 +1216,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::hexagon: case Triple::kalimba: case Triple::le32: + case Triple::asmjs: // @LOCALMOD Emscripten case Triple::mips: case Triple::mipsel: case Triple::nvptx: @@ -1256,6 +1266,7 @@ Triple Triple::get64BitArchVariant() const { case Triple::r600: case Triple::tce: case Triple::xcore: + case Triple::asmjs: // @LOCALMOD Emscripten case Triple::sparcel: case Triple::shave: T.setArch(UnknownArch); @@ -1313,6 +1324,7 @@ Triple Triple::getBigEndianArchVariant() const { case Triple::amdgcn: case Triple::amdil64: case Triple::amdil: + case Triple::asmjs: case Triple::avr: case Triple::hexagon: case Triple::hsail64: @@ -1393,6 +1405,7 @@ bool Triple::isLittleEndian() const { case Triple::amdil64: case Triple::amdil: case Triple::arm: + case Triple::asmjs: case Triple::avr: case Triple::bpfel: case Triple::hexagon: diff --git a/lib/Target/JSBackend/CMakeLists.txt b/lib/Target/JSBackend/CMakeLists.txt new file mode 100644 index 000000000000..697a30b3ad74 --- /dev/null +++ b/lib/Target/JSBackend/CMakeLists.txt @@ -0,0 +1,10 @@ +add_llvm_target(JSBackendCodeGen + JSBackend.cpp + JSTargetMachine.cpp + JSTargetTransformInfo.cpp + ) + +add_dependencies(LLVMJSBackendCodeGen intrinsics_gen) + +add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) diff --git a/lib/Target/JSBackend/JS.h b/lib/Target/JSBackend/JS.h new file mode 100644 index 000000000000..b674a85ab8f3 --- /dev/null +++ b/lib/Target/JSBackend/JS.h @@ -0,0 +1,24 @@ +//===-- JS.h - Top-level interface for JS representation ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the JS +// target library, as used by the LLVM JIT. +// +//===----------------------------------------------------------------------===// + +#ifndef TARGET_JS_H +#define TARGET_JS_H + +namespace llvm { + +class JSTargetMachine; + +} // End llvm namespace + +#endif diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp new file mode 100644 index 000000000000..f7f5f36eeeab --- /dev/null +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -0,0 +1,40 @@ +//===-- JSBackend.cpp - Library for converting LLVM code to JS -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements compiling of LLVM IR, which is assumed to have been +// simplified using the PNaCl passes, i64 legalization, and other necessary +// transformations, into JavaScript in asm.js format, suitable for passing +// to emscripten for final processing. +// +//===----------------------------------------------------------------------===// + +#include "JSTargetMachine.h" +#include "MCTargetDesc/JSBackendMCTargetDesc.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetLowering.h" + +using namespace llvm; + +extern "C" void LLVMInitializeJSBackendTarget() { + // Register the target. + RegisterTargetMachine X(TheJSBackendTarget); +} + +//===----------------------------------------------------------------------===// +// External Interface declaration +//===----------------------------------------------------------------------===// + +bool JSTargetMachine::addPassesToEmitFile( + PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, + bool DisableVerify, AnalysisID StartBefore, + AnalysisID StartAfter, AnalysisID StopAfter, + MachineFunctionInitializer *MFInitializer) { + return false; +} diff --git a/lib/Target/JSBackend/JSTargetMachine.cpp b/lib/Target/JSBackend/JSTargetMachine.cpp new file mode 100644 index 000000000000..2ae3dd6f6a92 --- /dev/null +++ b/lib/Target/JSBackend/JSTargetMachine.cpp @@ -0,0 +1,48 @@ +//===-- JSTargetMachine.cpp - Define TargetMachine for the JS -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the JS specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + +#include "JSTargetMachine.h" +#include "JSTargetTransformInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +extern const llvm::SubtargetFeatureKV JSSubTypeKV[] = { + { "asmjs", "Select the asmjs processor", { }, { } } +}; + +static const llvm::SubtargetInfoKV JSProcSchedModels[] = { + { "asmjs", &MCSchedModel::GetDefaultSchedModel() } +}; + +JSSubtarget::JSSubtarget(const TargetMachine& TM, const Triple &TT) : + TargetSubtargetInfo(TT, "asmjs", "asmjs", None, makeArrayRef(JSSubTypeKV, 1), JSProcSchedModels, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr), + TL(TM) + {} + + +JSTargetMachine::JSTargetMachine(const Target &T, const Triple &TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Optional& RM, CodeModel::Model CM, + CodeGenOpt::Level OL) + : LLVMTargetMachine(T, "e-p:32:32-i64:64-v128:32:128-n32-S128", TT, + CPU, FS, Options, Reloc::Static, CM, OL), + ST(*this, TT) { +} + +TargetIRAnalysis JSTargetMachine::getTargetIRAnalysis() { + return TargetIRAnalysis([this](const Function &F) { + return TargetTransformInfo(JSTTIImpl(this, F)); + }); +} + diff --git a/lib/Target/JSBackend/JSTargetMachine.h b/lib/Target/JSBackend/JSTargetMachine.h new file mode 100644 index 000000000000..71b79fe3b01b --- /dev/null +++ b/lib/Target/JSBackend/JSTargetMachine.h @@ -0,0 +1,71 @@ +//===-- JSTargetMachine.h - TargetMachine for the JS Backend ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file declares the TargetMachine that is used by the JS/asm.js/ +// emscripten backend. +// +//===---------------------------------------------------------------------===// + +#ifndef JSTARGETMACHINE_H +#define JSTARGETMACHINE_H + +#include "JS.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetLowering.h" + +namespace llvm { + +class formatted_raw_ostream; + +class JSTargetLowering : public TargetLowering { +public: + explicit JSTargetLowering(const TargetMachine& TM) : TargetLowering(TM) {} +}; + +class JSSubtarget : public TargetSubtargetInfo { + JSTargetLowering TL; + +public: + JSSubtarget(const TargetMachine& TM, const Triple &TT); + + const TargetLowering *getTargetLowering() const override { + return &TL; + } +}; + +class JSTargetMachine : public LLVMTargetMachine { + const JSSubtarget ST; + +public: + JSTargetMachine(const Target &T, const Triple &TT, + StringRef CPU, StringRef FS, const TargetOptions &Options, + Optional& RM, CodeModel::Model CM, + CodeGenOpt::Level OL); + + bool addPassesToEmitFile( + PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, + bool DisableVerify = true, AnalysisID StartBefore = nullptr, + AnalysisID StartAfter = nullptr, AnalysisID StopAfter = nullptr, + MachineFunctionInitializer *MFInitializer = nullptr) override; + + TargetIRAnalysis getTargetIRAnalysis() override; + + const TargetSubtargetInfo *getJSSubtargetImpl() const { + return &ST; + } + + const JSSubtarget *getSubtargetImpl(const Function &F) const override { + return &ST; + } +}; + +} // End llvm namespace + +#endif diff --git a/lib/Target/JSBackend/JSTargetTransformInfo.cpp b/lib/Target/JSBackend/JSTargetTransformInfo.cpp new file mode 100644 index 000000000000..c1e29fc3d8b2 --- /dev/null +++ b/lib/Target/JSBackend/JSTargetTransformInfo.cpp @@ -0,0 +1,118 @@ +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// \file +// This file implements a TargetTransformInfo analysis pass specific to the +// JS target machine. It uses the target's detailed information to provide +// more precise answers to certain TTI queries, while letting the target +// independent and default TTI implementations handle the rest. +// +//===----------------------------------------------------------------------===// + +#include "JSTargetTransformInfo.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/CodeGen/BasicTTIImpl.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/CostTable.h" +#include "llvm/Target/TargetLowering.h" +using namespace llvm; + +#define DEBUG_TYPE "JStti" + +void JSTTIImpl::getUnrollingPreferences(Loop *L, + TTI::UnrollingPreferences &UP) { + // We generally don't want a lot of unrolling. + UP.Partial = false; + UP.Runtime = false; +} + +unsigned JSTTIImpl::getNumberOfRegisters(bool Vector) { + if (Vector) return 16; // like NEON, x86_64, etc. + + return 8; // like x86, thumb, etc. +} + +unsigned JSTTIImpl::getRegisterBitWidth(bool Vector) { + if (Vector) { + return 128; + } + + return 32; +} + +static const unsigned Nope = 65536; + +// Certain types are fine, but some vector types must be avoided at all Costs. +static bool isOkType(Type *Ty) { + if (VectorType *VTy = dyn_cast(Ty)) { + if (VTy->getNumElements() != 4 || !(VTy->getElementType()->isIntegerTy(1) || + VTy->getElementType()->isIntegerTy(32) || + VTy->getElementType()->isFloatTy())) { + return false; + } + } + return true; +} + +unsigned JSTTIImpl::getArithmeticInstrCost( + unsigned Opcode, Type *Ty, TTI::OperandValueKind Opd1Info, + TTI::OperandValueKind Opd2Info, TTI::OperandValueProperties Opd1PropInfo, + TTI::OperandValueProperties Opd2PropInfo) { + + unsigned Cost = BasicTTIImplBase::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info); + + if (!isOkType(Ty)) + return Nope; + + if (VectorType *VTy = dyn_cast(Ty)) { + switch (Opcode) { + case Instruction::LShr: + case Instruction::AShr: + case Instruction::Shl: + // SIMD.js' shifts are currently only ByScalar. + if (Opd2Info != TTI::OK_UniformValue && Opd2Info != TTI::OK_UniformConstantValue) + Cost = Cost * VTy->getNumElements() + 100; + break; + } + } + return Cost; +} + +unsigned JSTTIImpl::getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) { + if (!isOkType(Val)) + return Nope; + + unsigned Cost = BasicTTIImplBase::getVectorInstrCost(Opcode, Val, Index); + + // SIMD.js' insert/extract currently only take constant indices. + if (Index == -1u) + return Cost + 100; + + return Cost; +} + + +unsigned JSTTIImpl::getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) { + if (!isOkType(Src)) + return Nope; + + return BasicTTIImplBase::getMemoryOpCost(Opcode, Src, Alignment, AddressSpace); +} + +unsigned JSTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) { + if (!isOkType(Src) || !isOkType(Dst)) + return Nope; + + return BasicTTIImplBase::getCastInstrCost(Opcode, Dst, Src); +} + diff --git a/lib/Target/JSBackend/JSTargetTransformInfo.h b/lib/Target/JSBackend/JSTargetTransformInfo.h new file mode 100644 index 000000000000..cf69ce0eb8c4 --- /dev/null +++ b/lib/Target/JSBackend/JSTargetTransformInfo.h @@ -0,0 +1,96 @@ +//===-- JSTargetTransformInfo.h - JS specific TTI -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file a TargetTransformInfo::Concept conforming object specific to the +/// JS target machine. It uses the target's detailed information to +/// provide more precise answers to certain TTI queries, while letting the +/// target independent and default TTI implementations handle the rest. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_JS_JSTARGETTRANSFORMINFO_H +#define LLVM_LIB_TARGET_JS_JSTARGETTRANSFORMINFO_H + +#include "JSTargetMachine.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/BasicTTIImpl.h" +#include "llvm/Target/TargetLowering.h" + +namespace llvm { + +class JSTTIImpl : public BasicTTIImplBase { + typedef BasicTTIImplBase BaseT; + typedef TargetTransformInfo TTI; + friend BaseT; + + const TargetSubtargetInfo *ST; + const TargetLoweringBase *TLI; + + const TargetSubtargetInfo *getST() const { return ST; } + const TargetLoweringBase *getTLI() const { return TLI; } + +public: + explicit JSTTIImpl(const JSTargetMachine *TM, const Function &F) + : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), + TLI(ST->getTargetLowering()) {} + + // Provide value semantics. MSVC requires that we spell all of these out. + JSTTIImpl(const JSTTIImpl &Arg) + : BaseT(static_cast(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + JSTTIImpl(JSTTIImpl &&Arg) + : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), + TLI(std::move(Arg.TLI)) {} +/* + JSTTIImpl &operator=(const JSTTIImpl &RHS) { + BaseT::operator=(static_cast(RHS)); + ST = RHS.ST; + TLI = RHS.TLI; + return *this; + } + JSTTIImpl &operator=(JSTTIImpl &&RHS) { + BaseT::operator=(std::move(static_cast(RHS))); + ST = std::move(RHS.ST); + TLI = std::move(RHS.TLI); + return *this; + } +*/ + + bool hasBranchDivergence() { return true; } + + void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP); + + TTI::PopcntSupportKind getPopcntSupport( + unsigned TyWidth) { + assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); + // Hopefully we'll get popcnt in ES7, but for now, we just have software. + return TargetTransformInfo::PSK_Software; + } + + unsigned getNumberOfRegisters(bool Vector); + + unsigned getRegisterBitWidth(bool Vector); + + unsigned getArithmeticInstrCost( + unsigned Opcode, Type *Ty, + TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, + TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, + TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, + TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None); + + unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index); + + unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace); + + unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src); +}; + +} // end namespace llvm + +#endif diff --git a/lib/Target/JSBackend/LLVMBuild.txt b/lib/Target/JSBackend/LLVMBuild.txt new file mode 100644 index 000000000000..96e39a4a8d45 --- /dev/null +++ b/lib/Target/JSBackend/LLVMBuild.txt @@ -0,0 +1,31 @@ +;===- ./lib/Target/JSBackend/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 +; +;===------------------------------------------------------------------------===; + +[common] +subdirectories = MCTargetDesc TargetInfo + +[component_0] +type = TargetGroup +name = JSBackend +parent = Target + +[component_1] +type = Library +name = JSBackendCodeGen +parent = JSBackend +required_libraries = Analysis CodeGen Core JSBackendInfo JSBackendDesc Support Target +add_to_library_groups = JSBackend diff --git a/lib/Target/JSBackend/MCTargetDesc/CMakeLists.txt b/lib/Target/JSBackend/MCTargetDesc/CMakeLists.txt new file mode 100644 index 000000000000..81c5eadef6a7 --- /dev/null +++ b/lib/Target/JSBackend/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,6 @@ +add_llvm_library(LLVMJSBackendDesc + JSBackendMCTargetDesc.cpp + ) + +# Hack: we need to include 'main' target directory to grab private headers +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..) diff --git a/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.cpp b/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.cpp new file mode 100644 index 000000000000..01b225ee4e3c --- /dev/null +++ b/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.cpp @@ -0,0 +1,22 @@ +//===-- JSBackendMCTargetDesc.cpp - JS Backend Target Descriptions --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides asm.js specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#include "JSBackendMCTargetDesc.h" +#include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +// Force static initialization. +extern "C" void LLVMInitializeJSBackendTargetMC() { + // nothing to register +} + diff --git a/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.h b/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.h new file mode 100644 index 000000000000..c98a55df83ba --- /dev/null +++ b/lib/Target/JSBackend/MCTargetDesc/JSBackendMCTargetDesc.h @@ -0,0 +1,25 @@ +//===- JSBackendMCTargetDesc.h - JS Backend Target Descriptions -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides asm.js specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef JSBACKENDMCTARGETDESC_H +#define JSBACKENDMCTARGETDESC_H + +#include "llvm/Support/TargetRegistry.h" + +namespace llvm { + +extern Target TheJSBackendTarget; + +} // End llvm namespace + +#endif diff --git a/lib/Target/JSBackend/MCTargetDesc/LLVMBuild.txt b/lib/Target/JSBackend/MCTargetDesc/LLVMBuild.txt new file mode 100644 index 000000000000..b7f3e6d89a00 --- /dev/null +++ b/lib/Target/JSBackend/MCTargetDesc/LLVMBuild.txt @@ -0,0 +1,24 @@ +;===- ./lib/Target/JSBackend/MCTargetDesc/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 = JSBackendDesc +parent = JSBackend +required_libraries = MC Support JSBackendInfo +add_to_library_groups = JSBackend + diff --git a/lib/Target/JSBackend/TargetInfo/CMakeLists.txt b/lib/Target/JSBackend/TargetInfo/CMakeLists.txt new file mode 100644 index 000000000000..29994eb8f95e --- /dev/null +++ b/lib/Target/JSBackend/TargetInfo/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMJSBackendInfo + JSBackendTargetInfo.cpp + ) diff --git a/lib/Target/JSBackend/TargetInfo/JSBackendTargetInfo.cpp b/lib/Target/JSBackend/TargetInfo/JSBackendTargetInfo.cpp new file mode 100644 index 000000000000..cdf9752a07e6 --- /dev/null +++ b/lib/Target/JSBackend/TargetInfo/JSBackendTargetInfo.cpp @@ -0,0 +1,20 @@ +//===-- JSBackendTargetInfo.cpp - JSBackend Target Implementation -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--------------------------------------------------------------------===// + +#include "JSTargetMachine.h" +#include "MCTargetDesc/JSBackendMCTargetDesc.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +Target llvm::TheJSBackendTarget; + +extern "C" void LLVMInitializeJSBackendTargetInfo() { + RegisterTarget X(TheJSBackendTarget, "js", "JavaScript (asm.js, emscripten) backend"); +} diff --git a/lib/Target/JSBackend/TargetInfo/LLVMBuild.txt b/lib/Target/JSBackend/TargetInfo/LLVMBuild.txt new file mode 100644 index 000000000000..732058260970 --- /dev/null +++ b/lib/Target/JSBackend/TargetInfo/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/JSBackend/TargetInfo/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 = JSBackendInfo +parent = JSBackend +required_libraries = MC Support Target +add_to_library_groups = JSBackend diff --git a/lib/Target/LLVMBuild.txt b/lib/Target/LLVMBuild.txt index 43621629dd25..5fabde06d09b 100644 --- a/lib/Target/LLVMBuild.txt +++ b/lib/Target/LLVMBuild.txt @@ -24,6 +24,7 @@ subdirectories = AArch64 AVR BPF + JSBackend Lanai Hexagon MSP430 diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index d75ed206ad23..66fce3934084 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -81,6 +81,9 @@ static bool mergeConstants(Module &M) { bool MadeChange = false; + // XXX EMSCRIPTEN: mark @__init_array_start as not to be touched + const GlobalValue *InitArrayStart = M.getNamedGlobal("__init_array_start"); + // Iterate constant merging while we are still making progress. Merging two // constants together may allow us to merge other constants together if the // second level constants have initializers which point to the globals that @@ -92,6 +95,10 @@ static bool mergeConstants(Module &M) { GVI != E; ) { GlobalVariable *GV = &*GVI++; + // XXX EMSCRIPTEN: mark @__init_array_start as not to be touched + if (GV == InitArrayStart) + continue; + // If this GV is dead, remove it. GV->removeDeadConstantUsers(); if (GV->use_empty() && GV->hasLocalLinkage()) { diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 961497fe3c2d..5d5b580eb55a 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2058,6 +2058,11 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, // smaller constant, which will be target friendly. unsigned Amt = ShAmt->getLimitedValue(TypeBits-1); if (LHSI->hasOneUse() && + // @LOCALMOD-BEGIN + // We don't want to introduce non-power-of-two integer sizes for PNaCl's + // stable wire format, so modify this transformation for NaCl. + isPowerOf2_32(TypeBits - Amt) && (TypeBits - Amt) >= 8 && + // @LOCALMOD-END Amt != 0 && RHSV.countTrailingZeros() >= Amt) { Type *NTy = IntegerType::get(ICI.getContext(), TypeBits - Amt); Constant *NCI = ConstantExpr::getTrunc(