Commit 20070e84 by Karl Schimpf

Cache common constants before lowering.

This code moves some constants used by the target lowering, so that they are defined (and cached) during static initialization of the target lowering, rather than looking up everytime they are used. This CL does this for the constant zero, and predefined helper functions. BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4076 R=jpp@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1775253003 .
parent 70e3f1cd
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceTimerTree.h" #include "IceTimerTree.h"
#include "IceTypes.def"
#include "IceTypes.h" #include "IceTypes.h"
#ifdef __clang__ #ifdef __clang__
...@@ -291,6 +292,18 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, ...@@ -291,6 +292,18 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
case FT_Iasm: case FT_Iasm:
break; break;
} }
// Cache up front common constants.
#define X(tag, sizeLog2, align, elts, elty, str, rcstr) \
ConstZeroForType[IceType_##tag] = getConstantZeroInternal(IceType_##tag);
ICETYPE_TABLE;
#undef X
ConstantTrue = getConstantInt1Internal(1);
// Define runtime helper functions.
#define X(Tag, Name) \
RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \
getConstantExternSym(Name);
RUNTIME_HELPER_FUNCTIONS_TABLE
#undef X
TargetLowering::staticInit(this); TargetLowering::staticInit(this);
} }
...@@ -657,24 +670,24 @@ Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) { ...@@ -657,24 +670,24 @@ Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
return nullptr; return nullptr;
} }
Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) { Constant *GlobalContext::getConstantInt1Internal(int8_t ConstantInt1) {
ConstantInt1 &= INT8_C(1); ConstantInt1 &= INT8_C(1);
return getConstPool()->Integers1.getOrAdd(this, ConstantInt1); return getConstPool()->Integers1.getOrAdd(this, ConstantInt1);
} }
Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) { Constant *GlobalContext::getConstantInt8Internal(int8_t ConstantInt8) {
return getConstPool()->Integers8.getOrAdd(this, ConstantInt8); return getConstPool()->Integers8.getOrAdd(this, ConstantInt8);
} }
Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) { Constant *GlobalContext::getConstantInt16Internal(int16_t ConstantInt16) {
return getConstPool()->Integers16.getOrAdd(this, ConstantInt16); return getConstPool()->Integers16.getOrAdd(this, ConstantInt16);
} }
Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) { Constant *GlobalContext::getConstantInt32Internal(int32_t ConstantInt32) {
return getConstPool()->Integers32.getOrAdd(this, ConstantInt32); return getConstPool()->Integers32.getOrAdd(this, ConstantInt32);
} }
Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) { Constant *GlobalContext::getConstantInt64Internal(int64_t ConstantInt64) {
return getConstPool()->Integers64.getOrAdd(this, ConstantInt64); return getConstPool()->Integers64.getOrAdd(this, ConstantInt64);
} }
...@@ -710,40 +723,33 @@ Constant *GlobalContext::getConstantUndef(Type Ty) { ...@@ -710,40 +723,33 @@ Constant *GlobalContext::getConstantUndef(Type Ty) {
return getConstPool()->Undefs.getOrAdd(this, Ty); return getConstPool()->Undefs.getOrAdd(this, Ty);
} }
// All locking is done by the getConstant*() target function.
Constant *GlobalContext::getConstantZero(Type Ty) { Constant *GlobalContext::getConstantZero(Type Ty) {
Constant *Zero = ConstZeroForType[Ty];
if (Zero == nullptr)
llvm::report_fatal_error("Unsupported constant type: " + typeIceString(Ty));
return Zero;
}
// All locking is done by the getConstant*() target function.
Constant *GlobalContext::getConstantZeroInternal(Type Ty) {
switch (Ty) { switch (Ty) {
case IceType_i1: case IceType_i1:
return getConstantInt1(0); return getConstantInt1Internal(0);
case IceType_i8: case IceType_i8:
return getConstantInt8(0); return getConstantInt8Internal(0);
case IceType_i16: case IceType_i16:
return getConstantInt16(0); return getConstantInt16Internal(0);
case IceType_i32: case IceType_i32:
return getConstantInt32(0); return getConstantInt32Internal(0);
case IceType_i64: case IceType_i64:
return getConstantInt64(0); return getConstantInt64Internal(0);
case IceType_f32: case IceType_f32:
return getConstantFloat(0); return getConstantFloat(0);
case IceType_f64: case IceType_f64:
return getConstantDouble(0); return getConstantDouble(0);
case IceType_v4i1: default:
case IceType_v8i1: return nullptr;
case IceType_v16i1:
case IceType_v16i8:
case IceType_v8i16:
case IceType_v4i32:
case IceType_v4f32: {
IceString Str;
llvm::raw_string_ostream BaseOS(Str);
BaseOS << "Unsupported constant type: " << Ty;
llvm_unreachable(BaseOS.str().c_str());
} break;
case IceType_void:
case IceType_NUM:
break;
} }
llvm_unreachable("Unknown type");
} }
ConstantList GlobalContext::getConstantPool(Type Ty) { ConstantList GlobalContext::getConstantPool(Type Ty) {
......
...@@ -21,12 +21,14 @@ ...@@ -21,12 +21,14 @@
#include "IceIntrinsics.h" #include "IceIntrinsics.h"
#include "IceRNG.h" #include "IceRNG.h"
#include "IceSwitchLowering.h" #include "IceSwitchLowering.h"
#include "IceTargetLowering.def"
#include "IceThreading.h" #include "IceThreading.h"
#include "IceTimerTree.h" #include "IceTimerTree.h"
#include "IceTypes.h" #include "IceTypes.h"
#include "IceUtils.h" #include "IceUtils.h"
#include <array> #include <array>
#include <cassert>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
...@@ -42,6 +44,15 @@ class ConstantPool; ...@@ -42,6 +44,15 @@ class ConstantPool;
class EmitterWorkItem; class EmitterWorkItem;
class FuncSigType; class FuncSigType;
// Runtime helper function IDs
enum class RuntimeHelper {
#define X(Tag, Name) H_##Tag,
RUNTIME_HELPER_FUNCTIONS_TABLE
#undef X
H_Num
};
/// LockedPtr is a way to provide automatically locked access to some object. /// LockedPtr is a way to provide automatically locked access to some object.
template <typename T> class LockedPtr { template <typename T> class LockedPtr {
LockedPtr() = delete; LockedPtr() = delete;
...@@ -189,11 +200,50 @@ public: ...@@ -189,11 +200,50 @@ public:
// getConstant*() functions are not const because they might add something to // getConstant*() functions are not const because they might add something to
// the constant pool. // the constant pool.
Constant *getConstantInt(Type Ty, int64_t Value); Constant *getConstantInt(Type Ty, int64_t Value);
Constant *getConstantInt1(int8_t ConstantInt1); Constant *getConstantInt1(int8_t ConstantInt1) {
Constant *getConstantInt8(int8_t ConstantInt8); ConstantInt1 &= INT8_C(1);
Constant *getConstantInt16(int16_t ConstantInt16); switch (ConstantInt1) {
Constant *getConstantInt32(int32_t ConstantInt32); case 0:
Constant *getConstantInt64(int64_t ConstantInt64); return getConstantZero(IceType_i1);
case 1:
return ConstantTrue;
default:
assert(false && "getConstantInt1 not on true/false");
return getConstantInt1Internal(ConstantInt1);
}
}
Constant *getConstantInt8(int8_t ConstantInt8) {
switch (ConstantInt8) {
case 0:
return getConstantZero(IceType_i8);
default:
return getConstantInt8Internal(ConstantInt8);
}
}
Constant *getConstantInt16(int16_t ConstantInt16) {
switch (ConstantInt16) {
case 0:
return getConstantZero(IceType_i16);
default:
return getConstantInt16Internal(ConstantInt16);
}
}
Constant *getConstantInt32(int32_t ConstantInt32) {
switch (ConstantInt32) {
case 0:
return getConstantZero(IceType_i32);
default:
return getConstantInt32Internal(ConstantInt32);
}
}
Constant *getConstantInt64(int64_t ConstantInt64) {
switch (ConstantInt64) {
case 0:
return getConstantZero(IceType_i64);
default:
return getConstantInt64Internal(ConstantInt64);
}
}
Constant *getConstantFloat(float Value); Constant *getConstantFloat(float Value);
Constant *getConstantDouble(double Value); Constant *getConstantDouble(double Value);
/// Returns a symbolic constant. /// Returns a symbolic constant.
...@@ -212,6 +262,12 @@ public: ...@@ -212,6 +262,12 @@ public:
/// Returns a copy of the list of external symbols. /// Returns a copy of the list of external symbols.
ConstantList getConstantExternSyms(); ConstantList getConstantExternSyms();
/// @} /// @}
Constant *getRuntimeHelperFunc(RuntimeHelper FuncID) const {
assert(FuncID < RuntimeHelper::H_Num);
Constant *Result = RuntimeHelperFunc[static_cast<size_t>(FuncID)];
assert(Result != nullptr && "No such runtime helper function");
return Result;
}
/// Return a locked pointer to the registered jump tables. /// Return a locked pointer to the registered jump tables.
JumpTableDataList getJumpTables(); JumpTableDataList getJumpTables();
...@@ -524,7 +580,18 @@ private: ...@@ -524,7 +580,18 @@ private:
/// Indicates if global variable declarations can be disposed of right after /// Indicates if global variable declarations can be disposed of right after
/// lowering. /// lowering.
bool DisposeGlobalVariablesAfterLowering = true; bool DisposeGlobalVariablesAfterLowering = true;
Constant *ConstZeroForType[IceType_NUM];
Constant *ConstantTrue;
// Holds the constants representing each runtime helper function.
Constant *RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_Num)];
Constant *getConstantZeroInternal(Type Ty);
Constant *getConstantIntInternal(Type Ty, int64_t Value);
Constant *getConstantInt1Internal(int8_t ConstantInt1);
Constant *getConstantInt8Internal(int8_t ConstantInt8);
Constant *getConstantInt16Internal(int16_t ConstantInt16);
Constant *getConstantInt32Internal(int32_t ConstantInt32);
Constant *getConstantInt64Internal(int64_t ConstantInt64);
LockedPtr<ArenaAllocator> getAllocator() { LockedPtr<ArenaAllocator> getAllocator() {
return LockedPtr<ArenaAllocator>(&Allocator, &AllocLock); return LockedPtr<ArenaAllocator>(&Allocator, &AllocLock);
} }
......
...@@ -697,10 +697,10 @@ void TargetLowering::assignVarStackSlots(VarList &SortedSpilledVariables, ...@@ -697,10 +697,10 @@ void TargetLowering::assignVarStackSlots(VarList &SortedSpilledVariables,
} }
} }
InstCall *TargetLowering::makeHelperCall(const IceString &Name, Variable *Dest, InstCall *TargetLowering::makeHelperCall(RuntimeHelper FuncID, Variable *Dest,
SizeT MaxSrcs) { SizeT MaxSrcs) {
constexpr bool HasTailCall = false; constexpr bool HasTailCall = false;
Constant *CallTarget = Ctx->getConstantExternSym(Name); Constant *CallTarget = Ctx->getRuntimeHelperFunc(FuncID);
InstCall *Call = InstCall *Call =
InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall); InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
return Call; return Call;
......
//===- subzero/src/IceTargetLowering.def - Target X-macros ------*- C++ -*-===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines certain platform independent patterns for lowering target
// instructions, in the form of x-macros.
//
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICETARGETLOWERING_DEF
#define SUBZERO_SRC_ICETARGETLOWERING_DEF
// Pattern for runtime helper functions
#define RUNTIME_HELPER_FUNCTIONS_TABLE \
/* tag , name */ \
X(bitcast_16xi1_i16, "__Sz_bitcast_16xi1_i16") \
X(bitcast_8xi1_i8, "__Sz_bitcast_8xi1_i8") \
X(bitcast_i16_16xi1, "__Sz_bitcast_i16_16xi1") \
X(bitcast_i8_8xi1, "__Sz_bitcast_i8_8xi1") \
X(call_ctpop_i32, "__popcountsi2") \
X(call_ctpop_i64, "__popcountdi2") \
X(call_longjmp, "longjmp") \
X(call_memcpy, "memcpy") \
X(call_memmove, "memmove") \
X(call_memset, "memset") \
X(call_read_tp, "__nacl_read_tp") \
X(call_setjmp, "setjmp") \
X(fptosi_f32_i64, "__Sz_fptosi_f32_i64") \
X(fptosi_f64_i64, "__Sz_fptosi_f64_i64") \
X(fptoui_4xi32_f32, "__Sz_fptoui_4xi32_f32") \
X(fptoui_f32_i32, "__Sz_fptoui_f32_i32") \
X(fptoui_f32_i64, "__Sz_fptoui_f32_i64") \
X(fptoui_f64_i32, "__Sz_fptoui_f64_i32") \
X(fptoui_f64_i64, "__Sz_fptoui_f64_i64") \
X(frem_f32, "fmodf") \
X(frem_f64, "fmod") \
X(sdiv_i32, "__divsi3") \
X(sdiv_i64, "__divdi3") \
X(sitofp_i64_f32, "__Sz_sitofp_i64_f32") \
X(sitofp_i64_f64, "__Sz_sitofp_i64_f64") \
X(srem_i32, "__modsi3") \
X(srem_i64, "__moddi3") \
X(udiv_i32, "__udivsi3") \
X(udiv_i64, "__udivdi3") \
X(uitofp_4xi32_4xf32, "__Sz_uitofp_4xi32_4xf32") \
X(uitofp_i32_f32, "__Sz_uitofp_i32_f32") \
X(uitofp_i32_f64, "__Sz_uitofp_i32_f64") \
X(uitofp_i64_f32, "__Sz_uitofp_i64_f32") \
X(uitofp_i64_f64, "__Sz_uitofp_i64_f64") \
X(urem_i32, "__umodsi3") \
X(urem_i64, "__umoddi3")
//#define X(Tag, Name)
#endif // SUBZERO_SRC_ICETARGETLOWERING_DEF
...@@ -461,9 +461,7 @@ protected: ...@@ -461,9 +461,7 @@ protected:
/// with the largest alignment need are placed in the front of the Dest list. /// with the largest alignment need are placed in the front of the Dest list.
void sortVarsByAlignment(VarList &Dest, const VarList &Source) const; void sortVarsByAlignment(VarList &Dest, const VarList &Source) const;
/// Make a call to an external helper function. InstCall *makeHelperCall(RuntimeHelper FuncID, Variable *Dest, SizeT MaxSrcs);
InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
SizeT MaxSrcs);
void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); } void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); }
...@@ -569,44 +567,7 @@ protected: ...@@ -569,44 +567,7 @@ protected:
LoweringContext Context; LoweringContext Context;
const SandboxType SandboxingType = ST_None; const SandboxType SandboxingType = ST_None;
// Runtime helper function names
const static constexpr char *H_bitcast_16xi1_i16 = "__Sz_bitcast_16xi1_i16";
const static constexpr char *H_bitcast_8xi1_i8 = "__Sz_bitcast_8xi1_i8";
const static constexpr char *H_bitcast_i16_16xi1 = "__Sz_bitcast_i16_16xi1";
const static constexpr char *H_bitcast_i8_8xi1 = "__Sz_bitcast_i8_8xi1";
const static constexpr char *H_call_ctpop_i32 = "__popcountsi2";
const static constexpr char *H_call_ctpop_i64 = "__popcountdi2";
const static constexpr char *H_call_longjmp = "longjmp";
const static constexpr char *H_call_memcpy = "memcpy";
const static constexpr char *H_call_memmove = "memmove";
const static constexpr char *H_call_memset = "memset";
const static constexpr char *H_call_read_tp = "__nacl_read_tp";
const static constexpr char *H_call_setjmp = "setjmp";
const static constexpr char *H_fptosi_f32_i64 = "__Sz_fptosi_f32_i64";
const static constexpr char *H_fptosi_f64_i64 = "__Sz_fptosi_f64_i64";
const static constexpr char *H_fptoui_4xi32_f32 = "__Sz_fptoui_4xi32_f32";
const static constexpr char *H_fptoui_f32_i32 = "__Sz_fptoui_f32_i32";
const static constexpr char *H_fptoui_f32_i64 = "__Sz_fptoui_f32_i64";
const static constexpr char *H_fptoui_f64_i32 = "__Sz_fptoui_f64_i32";
const static constexpr char *H_fptoui_f64_i64 = "__Sz_fptoui_f64_i64";
const static constexpr char *H_frem_f32 = "fmodf";
const static constexpr char *H_frem_f64 = "fmod";
const static constexpr char *H_getIP_prefix = "__Sz_getIP_"; const static constexpr char *H_getIP_prefix = "__Sz_getIP_";
const static constexpr char *H_sdiv_i32 = "__divsi3";
const static constexpr char *H_sdiv_i64 = "__divdi3";
const static constexpr char *H_sitofp_i64_f32 = "__Sz_sitofp_i64_f32";
const static constexpr char *H_sitofp_i64_f64 = "__Sz_sitofp_i64_f64";
const static constexpr char *H_srem_i32 = "__modsi3";
const static constexpr char *H_srem_i64 = "__moddi3";
const static constexpr char *H_udiv_i32 = "__udivsi3";
const static constexpr char *H_udiv_i64 = "__udivdi3";
const static constexpr char *H_uitofp_4xi32_4xf32 = "__Sz_uitofp_4xi32_4xf32";
const static constexpr char *H_uitofp_i32_f32 = "__Sz_uitofp_i32_f32";
const static constexpr char *H_uitofp_i32_f64 = "__Sz_uitofp_i32_f64";
const static constexpr char *H_uitofp_i64_f32 = "__Sz_uitofp_i64_f32";
const static constexpr char *H_uitofp_i64_f64 = "__Sz_uitofp_i64_f64";
const static constexpr char *H_urem_i32 = "__umodsi3";
const static constexpr char *H_urem_i64 = "__umoddi3";
}; };
/// TargetDataLowering is used for "lowering" data including initializers for /// TargetDataLowering is used for "lowering" data including initializers for
......
...@@ -468,24 +468,24 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -468,24 +468,24 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
// Technically, ARM has its own aeabi routines, but we can use the // Technically, ARM has its own aeabi routines, but we can use the
// non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div, but uses // non-aeabi routine as well. LLVM uses __aeabi_ldivmod for div, but uses
// the more standard __moddi3 for rem. // the more standard __moddi3 for rem.
Operand *TargetHelper = nullptr; RuntimeHelper HelperID = RuntimeHelper::H_Num;
switch (Op) { switch (Op) {
default: default:
return; return;
case InstArithmetic::Udiv: case InstArithmetic::Udiv:
TargetHelper = Ctx->getConstantExternSym(H_udiv_i64); HelperID = RuntimeHelper::H_udiv_i64;
break; break;
case InstArithmetic::Sdiv: case InstArithmetic::Sdiv:
TargetHelper = Ctx->getConstantExternSym(H_sdiv_i64); HelperID = RuntimeHelper::H_sdiv_i64;
break; break;
case InstArithmetic::Urem: case InstArithmetic::Urem:
TargetHelper = Ctx->getConstantExternSym(H_urem_i64); HelperID = RuntimeHelper::H_urem_i64;
break; break;
case InstArithmetic::Srem: case InstArithmetic::Srem:
TargetHelper = Ctx->getConstantExternSym(H_srem_i64); HelperID = RuntimeHelper::H_srem_i64;
break; break;
} }
assert(TargetHelper != nullptr); Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID);
ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
...@@ -500,33 +500,29 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -500,33 +500,29 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
case IceType_i8: { case IceType_i8: {
const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm); const bool HasHWDiv = hasCPUFeature(TargetARM32Features::HWDivArm);
InstCast::OpKind CastKind; InstCast::OpKind CastKind;
Operand *TargetHelper; RuntimeHelper HelperID = RuntimeHelper::H_Num;
switch (Op) { switch (Op) {
default: default:
return; return;
case InstArithmetic::Udiv: case InstArithmetic::Udiv:
TargetHelper = HelperID = HasHWDiv ? RuntimeHelper::H_Num : RuntimeHelper::H_udiv_i32;
HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_udiv_i32);
CastKind = InstCast::Zext; CastKind = InstCast::Zext;
break; break;
case InstArithmetic::Sdiv: case InstArithmetic::Sdiv:
TargetHelper = HelperID = HasHWDiv ? RuntimeHelper::H_Num : RuntimeHelper::H_sdiv_i32;
HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_sdiv_i32);
CastKind = InstCast::Sext; CastKind = InstCast::Sext;
break; break;
case InstArithmetic::Urem: case InstArithmetic::Urem:
TargetHelper = HelperID = HasHWDiv ? RuntimeHelper::H_Num : RuntimeHelper::H_urem_i32;
HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_urem_i32);
CastKind = InstCast::Zext; CastKind = InstCast::Zext;
break; break;
case InstArithmetic::Srem: case InstArithmetic::Srem:
TargetHelper = HelperID = HasHWDiv ? RuntimeHelper::H_Num : RuntimeHelper::H_srem_i32;
HasHWDiv ? nullptr : Ctx->getConstantExternSym(H_srem_i32);
CastKind = InstCast::Sext; CastKind = InstCast::Sext;
break; break;
} }
if (TargetHelper == nullptr) { if (HelperID == RuntimeHelper::H_Num) {
// TargetHelper should only ever be nullptr when the processor does not // HelperID should only ever be undefined when the processor does not
// have a hardware divider. If any other helpers are ever introduced, // have a hardware divider. If any other helpers are ever introduced,
// the following assert will have to be modified. // the following assert will have to be modified.
assert(HasHWDiv); assert(HasHWDiv);
...@@ -560,7 +556,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -560,7 +556,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
Src1 = Src1_32; Src1 = Src1_32;
} }
} }
assert(TargetHelper != nullptr); Operand *TargetHelper = Ctx->getRuntimeHelperFunc(HelperID);
ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
...@@ -578,8 +574,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -578,8 +574,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
return; return;
} }
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
Operand *TargetHelper = Ctx->getConstantExternSym( Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); DestTy == IceType_f32 ? RuntimeHelper::H_frem_f32
: RuntimeHelper::H_frem_f64);
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(Instr->getSrc(0)); Call->addArg(Instr->getSrc(0));
...@@ -619,9 +616,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -619,9 +616,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
} }
const bool DestIsSigned = CastKind == InstCast::Fptosi; const bool DestIsSigned = CastKind == InstCast::Fptosi;
const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy); const bool Src0IsF32 = isFloat32Asserting32Or64(SrcTy);
Operand *TargetHelper = Ctx->getConstantExternSym( Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) Src0IsF32 ? (DestIsSigned ? RuntimeHelper::H_fptosi_f32_i64
: (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); : RuntimeHelper::H_fptoui_f32_i64)
: (DestIsSigned ? RuntimeHelper::H_fptosi_f64_i64
: RuntimeHelper::H_fptoui_f64_i64));
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
...@@ -636,9 +635,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -636,9 +635,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
} }
const bool SourceIsSigned = CastKind == InstCast::Sitofp; const bool SourceIsSigned = CastKind == InstCast::Sitofp;
const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType()); const bool DestIsF32 = isFloat32Asserting32Or64(Dest->getType());
Operand *TargetHelper = Ctx->getConstantExternSym( Operand *TargetHelper = Ctx->getRuntimeHelperFunc(
DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) DestIsF32 ? (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f32
: (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); : RuntimeHelper::H_uitofp_i64_f32)
: (SourceIsSigned ? RuntimeHelper::H_sitofp_i64_f64
: RuntimeHelper::H_uitofp_i64_f64));
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
...@@ -651,23 +652,23 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -651,23 +652,23 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
return; return;
} }
Variable *CallDest = Dest; Variable *CallDest = Dest;
const char *HelperName = nullptr; RuntimeHelper HelperID = RuntimeHelper::H_Num;
switch (DestTy) { switch (DestTy) {
default: default:
return; return;
case IceType_i8: case IceType_i8:
assert(SrcTy == IceType_v8i1); assert(SrcTy == IceType_v8i1);
HelperName = H_bitcast_8xi1_i8; HelperID = RuntimeHelper::H_bitcast_8xi1_i8;
CallDest = Func->makeVariable(IceType_i32); CallDest = Func->makeVariable(IceType_i32);
break; break;
case IceType_i16: case IceType_i16:
assert(SrcTy == IceType_v16i1); assert(SrcTy == IceType_v16i1);
HelperName = H_bitcast_16xi1_i16; HelperID = RuntimeHelper::H_bitcast_16xi1_i16;
CallDest = Func->makeVariable(IceType_i32); CallDest = Func->makeVariable(IceType_i32);
break; break;
case IceType_v8i1: { case IceType_v8i1: {
assert(SrcTy == IceType_i8); assert(SrcTy == IceType_i8);
HelperName = H_bitcast_i8_8xi1; HelperID = RuntimeHelper::H_bitcast_i8_8xi1;
Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide. // Arguments to functions are required to be at least 32 bits wide.
Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
...@@ -675,16 +676,15 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -675,16 +676,15 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
} break; } break;
case IceType_v16i1: { case IceType_v16i1: {
assert(SrcTy == IceType_i16); assert(SrcTy == IceType_i16);
HelperName = H_bitcast_i16_16xi1; HelperID = RuntimeHelper::H_bitcast_i16_16xi1;
Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide. // Arguments to functions are required to be at least 32 bits wide.
Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
Src0 = Src0AsI32; Src0 = Src0AsI32;
} break; } break;
} }
assert(HelperName != nullptr);
constexpr SizeT MaxSrcs = 1; constexpr SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall(HelperName, CallDest, MaxSrcs); InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs);
Call->addArg(Src0); Call->addArg(Src0);
Context.insert(Call); Context.insert(Call);
// The PNaCl ABI disallows i8/i16 return types, so truncate the helper // The PNaCl ABI disallows i8/i16 return types, so truncate the helper
...@@ -706,9 +706,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -706,9 +706,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
return; return;
case Intrinsics::Ctpop: { case Intrinsics::Ctpop: {
Operand *Src0 = IntrinsicCall->getArg(0); Operand *Src0 = IntrinsicCall->getArg(0);
Operand *TargetHelper = Ctx->getConstantExternSym( Operand *TargetHelper =
isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 Ctx->getRuntimeHelperFunc(isInt32Asserting32Or64(Src0->getType())
: H_call_ctpop_i64); ? RuntimeHelper::H_call_ctpop_i32
: RuntimeHelper::H_call_ctpop_i64);
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
...@@ -722,7 +723,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -722,7 +723,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
case Intrinsics::Longjmp: { case Intrinsics::Longjmp: {
static constexpr SizeT MaxArgs = 2; static constexpr SizeT MaxArgs = 2;
static constexpr Variable *NoDest = nullptr; static constexpr Variable *NoDest = nullptr;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_longjmp); Operand *TargetHelper =
Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_longjmp);
auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(IntrinsicCall->getArg(0)); Call->addArg(IntrinsicCall->getArg(0));
...@@ -735,7 +737,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -735,7 +737,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
// for intrinsic calls w/ a known length. // for intrinsic calls w/ a known length.
static constexpr SizeT MaxArgs = 3; static constexpr SizeT MaxArgs = 3;
static constexpr Variable *NoDest = nullptr; static constexpr Variable *NoDest = nullptr;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memcpy); Operand *TargetHelper =
Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memcpy);
auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(IntrinsicCall->getArg(0)); Call->addArg(IntrinsicCall->getArg(0));
...@@ -747,7 +750,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -747,7 +750,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
case Intrinsics::Memmove: { case Intrinsics::Memmove: {
static constexpr SizeT MaxArgs = 3; static constexpr SizeT MaxArgs = 3;
static constexpr Variable *NoDest = nullptr; static constexpr Variable *NoDest = nullptr;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memmove); Operand *TargetHelper =
Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memmove);
auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(IntrinsicCall->getArg(0)); Call->addArg(IntrinsicCall->getArg(0));
...@@ -769,7 +773,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -769,7 +773,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
// decide to use __aeabi_memset. // decide to use __aeabi_memset.
static constexpr SizeT MaxArgs = 3; static constexpr SizeT MaxArgs = 3;
static constexpr Variable *NoDest = nullptr; static constexpr Variable *NoDest = nullptr;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_memset); Operand *TargetHelper =
Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_memset);
auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, NoDest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(IntrinsicCall->getArg(0)); Call->addArg(IntrinsicCall->getArg(0));
...@@ -783,9 +788,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -783,9 +788,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
return; return;
} }
static constexpr SizeT MaxArgs = 0; static constexpr SizeT MaxArgs = 0;
const char *ReadTP = Operand *TargetHelper =
SandboxingType == ST_Nonsfi ? "__aeabi_read_tp" : H_call_read_tp; SandboxingType == ST_Nonsfi
Operand *TargetHelper = Ctx->getConstantExternSym(ReadTP); ? Ctx->getConstantExternSym("__aeabi_read_tp")
: Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_read_tp);
Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall, Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall,
IsTargetHelperCall); IsTargetHelperCall);
Instr->setDeleted(); Instr->setDeleted();
...@@ -793,7 +799,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -793,7 +799,8 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
} }
case Intrinsics::Setjmp: { case Intrinsics::Setjmp: {
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_setjmp); Operand *TargetHelper =
Ctx->getRuntimeHelperFunc(RuntimeHelper::H_call_setjmp);
auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(IntrinsicCall->getArg(0)); Call->addArg(IntrinsicCall->getArg(0));
......
...@@ -1010,7 +1010,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -1010,7 +1010,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::Longjmp: { case Intrinsics::Longjmp: {
InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_longjmp, nullptr, 2);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1)); Call->addArg(Instr->getArg(1));
lowerCall(Call); lowerCall(Call);
...@@ -1019,7 +1019,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -1019,7 +1019,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case Intrinsics::Memcpy: { case Intrinsics::Memcpy: {
// In the future, we could potentially emit an inline memcpy/memset, etc. // In the future, we could potentially emit an inline memcpy/memset, etc.
// for intrinsic calls w/ a known length. // for intrinsic calls w/ a known length.
InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memcpy, nullptr, 3);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1)); Call->addArg(Instr->getArg(1));
Call->addArg(Instr->getArg(2)); Call->addArg(Instr->getArg(2));
...@@ -1027,7 +1027,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -1027,7 +1027,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::Memmove: { case Intrinsics::Memmove: {
InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memmove, nullptr, 3);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1)); Call->addArg(Instr->getArg(1));
Call->addArg(Instr->getArg(2)); Call->addArg(Instr->getArg(2));
...@@ -1041,7 +1041,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -1041,7 +1041,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
assert(ValOp->getType() == IceType_i8); assert(ValOp->getType() == IceType_i8);
Variable *ValExt = Func->makeVariable(stackSlotType()); Variable *ValExt = Func->makeVariable(stackSlotType());
lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memset, nullptr, 3);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
Call->addArg(ValExt); Call->addArg(ValExt);
Call->addArg(Instr->getArg(2)); Call->addArg(Instr->getArg(2));
...@@ -1052,13 +1052,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -1052,13 +1052,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
if (Ctx->getFlags().getUseSandboxing()) { if (Ctx->getFlags().getUseSandboxing()) {
UnimplementedLoweringError(this, Instr); UnimplementedLoweringError(this, Instr);
} else { } else {
InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); InstCall *Call =
makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0);
lowerCall(Call); lowerCall(Call);
} }
return; return;
} }
case Intrinsics::Setjmp: { case Intrinsics::Setjmp: {
InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1); InstCall *Call =
makeHelperCall(RuntimeHelper::H_call_setjmp, Instr->getDest(), 1);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
lowerCall(Call); lowerCall(Call);
return; return;
......
...@@ -74,7 +74,7 @@ private: ...@@ -74,7 +74,7 @@ private:
Operand *createNaClReadTPSrcOperand() { Operand *createNaClReadTPSrcOperand() {
Variable *TDB = makeReg(IceType_i32); Variable *TDB = makeReg(IceType_i32);
InstCall *Call = makeHelperCall(H_call_read_tp, TDB, 0); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_read_tp, TDB, 0);
lowerCall(Call); lowerCall(Call);
return TDB; return TDB;
} }
......
...@@ -4061,8 +4061,10 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall( ...@@ -4061,8 +4061,10 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall(
ValTy = IceType_i64; ValTy = IceType_i64;
} }
InstCall *Call = makeHelperCall( InstCall *Call =
ValTy == IceType_i32 ? H_call_ctpop_i32 : H_call_ctpop_i64, T, 1); makeHelperCall(ValTy == IceType_i32 ? RuntimeHelper::H_call_ctpop_i32
: RuntimeHelper::H_call_ctpop_i64,
T, 1);
Call->addArg(Val); Call->addArg(Val);
lowerCall(Call); lowerCall(Call);
// The popcount helpers always return 32-bit values, while the intrinsic's // The popcount helpers always return 32-bit values, while the intrinsic's
...@@ -4155,7 +4157,7 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall( ...@@ -4155,7 +4157,7 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall(
return; return;
} }
case Intrinsics::Longjmp: { case Intrinsics::Longjmp: {
InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_longjmp, nullptr, 2);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1)); Call->addArg(Instr->getArg(1));
lowerCall(Call); lowerCall(Call);
...@@ -4182,13 +4184,15 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall( ...@@ -4182,13 +4184,15 @@ void TargetX86Base<TraitsType>::lowerIntrinsicCall(
_mov(T, Src); _mov(T, Src);
_mov(Dest, T); _mov(Dest, T);
} else { } else {
InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); InstCall *Call =
makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0);
lowerCall(Call); lowerCall(Call);
} }
return; return;
} }
case Intrinsics::Setjmp: { case Intrinsics::Setjmp: {
InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1); InstCall *Call =
makeHelperCall(RuntimeHelper::H_call_setjmp, Instr->getDest(), 1);
Call->addArg(Instr->getArg(0)); Call->addArg(Instr->getArg(0));
lowerCall(Call); lowerCall(Call);
return; return;
...@@ -4762,7 +4766,7 @@ void TargetX86Base<TraitsType>::lowerMemcpy(Operand *Dest, Operand *Src, ...@@ -4762,7 +4766,7 @@ void TargetX86Base<TraitsType>::lowerMemcpy(Operand *Dest, Operand *Src,
} }
// Fall back on a function call // Fall back on a function call
InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memcpy, nullptr, 3);
Call->addArg(Dest); Call->addArg(Dest);
Call->addArg(Src); Call->addArg(Src);
Call->addArg(Count); Call->addArg(Count);
...@@ -4834,7 +4838,7 @@ void TargetX86Base<TraitsType>::lowerMemmove(Operand *Dest, Operand *Src, ...@@ -4834,7 +4838,7 @@ void TargetX86Base<TraitsType>::lowerMemmove(Operand *Dest, Operand *Src,
} }
// Fall back on a function call // Fall back on a function call
InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memmove, nullptr, 3);
Call->addArg(Dest); Call->addArg(Dest);
Call->addArg(Src); Call->addArg(Src);
Call->addArg(Count); Call->addArg(Count);
...@@ -4943,7 +4947,7 @@ void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val, ...@@ -4943,7 +4947,7 @@ void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val,
lowerCast(InstCast::create(Func, InstCast::Zext, ValExtVar, Val)); lowerCast(InstCast::create(Func, InstCast::Zext, ValExtVar, Val));
ValExt = ValExtVar; ValExt = ValExtVar;
} }
InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); InstCall *Call = makeHelperCall(RuntimeHelper::H_call_memset, nullptr, 3);
Call->addArg(Dest); Call->addArg(Dest);
Call->addArg(ValExt); Call->addArg(ValExt);
Call->addArg(Count); Call->addArg(Count);
...@@ -6209,7 +6213,7 @@ template <typename TraitsType> ...@@ -6209,7 +6213,7 @@ template <typename TraitsType>
void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
uint32_t StackArgumentsSize = 0; uint32_t StackArgumentsSize = 0;
if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) { if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) {
const char *HelperName = nullptr; RuntimeHelper HelperID = RuntimeHelper::H_Num;
Variable *Dest = Arith->getDest(); Variable *Dest = Arith->getDest();
Type DestTy = Dest->getType(); Type DestTy = Dest->getType();
if (!Traits::Is64Bit && DestTy == IceType_i64) { if (!Traits::Is64Bit && DestTy == IceType_i64) {
...@@ -6217,16 +6221,16 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6217,16 +6221,16 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
default: default:
return; return;
case InstArithmetic::Udiv: case InstArithmetic::Udiv:
HelperName = H_udiv_i64; HelperID = RuntimeHelper::H_udiv_i64;
break; break;
case InstArithmetic::Sdiv: case InstArithmetic::Sdiv:
HelperName = H_sdiv_i64; HelperID = RuntimeHelper::H_sdiv_i64;
break; break;
case InstArithmetic::Urem: case InstArithmetic::Urem:
HelperName = H_urem_i64; HelperID = RuntimeHelper::H_urem_i64;
break; break;
case InstArithmetic::Srem: case InstArithmetic::Srem:
HelperName = H_srem_i64; HelperID = RuntimeHelper::H_srem_i64;
break; break;
} }
} else if (isVectorType(DestTy)) { } else if (isVectorType(DestTy)) {
...@@ -6260,13 +6264,13 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6260,13 +6264,13 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
return; return;
case InstArithmetic::Frem: case InstArithmetic::Frem:
if (isFloat32Asserting32Or64(DestTy)) if (isFloat32Asserting32Or64(DestTy))
HelperName = H_frem_f32; HelperID = RuntimeHelper::H_frem_f32;
else else
HelperName = H_frem_f64; HelperID = RuntimeHelper::H_frem_f64;
} }
} }
constexpr SizeT MaxSrcs = 2; constexpr SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall(HelperName, Dest, MaxSrcs); InstCall *Call = makeHelperCall(HelperID, Dest, MaxSrcs);
Call->addArg(Arith->getSrc(0)); Call->addArg(Arith->getSrc(0));
Call->addArg(Arith->getSrc(1)); Call->addArg(Arith->getSrc(1));
StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); StackArgumentsSize = getCallStackArgumentsSizeBytes(Call);
...@@ -6278,15 +6282,16 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6278,15 +6282,16 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
const Type SrcType = Src0->getType(); const Type SrcType = Src0->getType();
Variable *Dest = Cast->getDest(); Variable *Dest = Cast->getDest();
const Type DestTy = Dest->getType(); const Type DestTy = Dest->getType();
const char *HelperName = nullptr; RuntimeHelper HelperID = RuntimeHelper::H_Num;
Variable *CallDest = Dest; Variable *CallDest = Dest;
switch (CastKind) { switch (CastKind) {
default: default:
return; return;
case InstCast::Fptosi: case InstCast::Fptosi:
if (!Traits::Is64Bit && DestTy == IceType_i64) { if (!Traits::Is64Bit && DestTy == IceType_i64) {
HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptosi_f32_i64 HelperID = isFloat32Asserting32Or64(SrcType)
: H_fptosi_f64_i64; ? RuntimeHelper::H_fptosi_f32_i64
: RuntimeHelper::H_fptosi_f64_i64;
} else { } else {
return; return;
} }
...@@ -6294,18 +6299,21 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6294,18 +6299,21 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
case InstCast::Fptoui: case InstCast::Fptoui:
if (isVectorType(DestTy)) { if (isVectorType(DestTy)) {
assert(DestTy == IceType_v4i32 && SrcType == IceType_v4f32); assert(DestTy == IceType_v4i32 && SrcType == IceType_v4f32);
HelperName = H_fptoui_4xi32_f32; HelperID = RuntimeHelper::H_fptoui_4xi32_f32;
} else if (DestTy == IceType_i64 || } else if (DestTy == IceType_i64 ||
(!Traits::Is64Bit && DestTy == IceType_i32)) { (!Traits::Is64Bit && DestTy == IceType_i32)) {
if (Traits::Is64Bit) { if (Traits::Is64Bit) {
HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64 HelperID = isFloat32Asserting32Or64(SrcType)
: H_fptoui_f64_i64; ? RuntimeHelper::H_fptoui_f32_i64
: RuntimeHelper::H_fptoui_f64_i64;
} else if (isInt32Asserting32Or64(DestTy)) { } else if (isInt32Asserting32Or64(DestTy)) {
HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i32 HelperID = isFloat32Asserting32Or64(SrcType)
: H_fptoui_f64_i32; ? RuntimeHelper::H_fptoui_f32_i32
: RuntimeHelper::H_fptoui_f64_i32;
} else { } else {
HelperName = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64 HelperID = isFloat32Asserting32Or64(SrcType)
: H_fptoui_f64_i64; ? RuntimeHelper::H_fptoui_f32_i64
: RuntimeHelper::H_fptoui_f64_i64;
} }
} else { } else {
return; return;
...@@ -6313,8 +6321,9 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6313,8 +6321,9 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
break; break;
case InstCast::Sitofp: case InstCast::Sitofp:
if (!Traits::Is64Bit && SrcType == IceType_i64) { if (!Traits::Is64Bit && SrcType == IceType_i64) {
HelperName = isFloat32Asserting32Or64(DestTy) ? H_sitofp_i64_f32 HelperID = isFloat32Asserting32Or64(DestTy)
: H_sitofp_i64_f64; ? RuntimeHelper::H_sitofp_i64_f32
: RuntimeHelper::H_sitofp_i64_f64;
} else { } else {
return; return;
} }
...@@ -6322,15 +6331,17 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6322,15 +6331,17 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
case InstCast::Uitofp: case InstCast::Uitofp:
if (isVectorType(SrcType)) { if (isVectorType(SrcType)) {
assert(DestTy == IceType_v4f32 && SrcType == IceType_v4i32); assert(DestTy == IceType_v4f32 && SrcType == IceType_v4i32);
HelperName = H_uitofp_4xi32_4xf32; HelperID = RuntimeHelper::H_uitofp_4xi32_4xf32;
} else if (SrcType == IceType_i64 || } else if (SrcType == IceType_i64 ||
(!Traits::Is64Bit && SrcType == IceType_i32)) { (!Traits::Is64Bit && SrcType == IceType_i32)) {
if (isInt32Asserting32Or64(SrcType)) { if (isInt32Asserting32Or64(SrcType)) {
HelperName = isFloat32Asserting32Or64(DestTy) ? H_uitofp_i32_f32 HelperID = isFloat32Asserting32Or64(DestTy)
: H_uitofp_i32_f64; ? RuntimeHelper::H_uitofp_i32_f32
: RuntimeHelper::H_uitofp_i32_f64;
} else { } else {
HelperName = isFloat32Asserting32Or64(DestTy) ? H_uitofp_i64_f32 HelperID = isFloat32Asserting32Or64(DestTy)
: H_uitofp_i64_f64; ? RuntimeHelper::H_uitofp_i64_f32
: RuntimeHelper::H_uitofp_i64_f64;
} }
} else { } else {
return; return;
...@@ -6344,17 +6355,17 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6344,17 +6355,17 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
return; return;
case IceType_i8: case IceType_i8:
assert(Src0->getType() == IceType_v8i1); assert(Src0->getType() == IceType_v8i1);
HelperName = H_bitcast_8xi1_i8; HelperID = RuntimeHelper::H_bitcast_8xi1_i8;
CallDest = Func->makeVariable(IceType_i32); CallDest = Func->makeVariable(IceType_i32);
break; break;
case IceType_i16: case IceType_i16:
assert(Src0->getType() == IceType_v16i1); assert(Src0->getType() == IceType_v16i1);
HelperName = H_bitcast_16xi1_i16; HelperID = RuntimeHelper::H_bitcast_16xi1_i16;
CallDest = Func->makeVariable(IceType_i32); CallDest = Func->makeVariable(IceType_i32);
break; break;
case IceType_v8i1: { case IceType_v8i1: {
assert(Src0->getType() == IceType_i8); assert(Src0->getType() == IceType_i8);
HelperName = H_bitcast_i8_8xi1; HelperID = RuntimeHelper::H_bitcast_i8_8xi1;
Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide. // Arguments to functions are required to be at least 32 bits wide.
Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
...@@ -6362,7 +6373,7 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6362,7 +6373,7 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
} break; } break;
case IceType_v16i1: { case IceType_v16i1: {
assert(Src0->getType() == IceType_i16); assert(Src0->getType() == IceType_i16);
HelperName = H_bitcast_i16_16xi1; HelperID = RuntimeHelper::H_bitcast_i16_16xi1;
Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide. // Arguments to functions are required to be at least 32 bits wide.
Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
...@@ -6372,7 +6383,7 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) { ...@@ -6372,7 +6383,7 @@ void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
} break; } break;
} }
constexpr SizeT MaxSrcs = 1; constexpr SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall(HelperName, CallDest, MaxSrcs); InstCall *Call = makeHelperCall(HelperID, CallDest, MaxSrcs);
Call->addArg(Src0); Call->addArg(Src0);
StackArgumentsSize = getCallStackArgumentsSizeBytes(Call); StackArgumentsSize = getCallStackArgumentsSizeBytes(Call);
Context.insert(Call); Context.insert(Call);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment