Commit 1d937a8e by John Porto

Subzero. Introduces a new LoweringContext::insert() method.

Emitting an instruction in Subzero requires a fair amount of boilerplated code: Context.insert(<InstType>::create(Func, <Args>...)); The ordeal is worse if one needs access to the recently create instructionL auto *Instr = <InstType>::create(Func, <Args>...); Context.insert(Instr); Instr->... This CL introduces a new LoweringContext::insert() method: template <<InstType>, <Args>...> <InstType> *LoweringContext::insert(<Args>...) { auto *New = Inst::create(Node.Cfg, <Args>...); insert(New); return New; } This is essentially a syntatic sugar that allows instructions to be emitted by using Context.insert<InstType>(<Args>...); The compiler should be able to inline the calls (and get rid of the return value) when appropriate. make bloat reviews a small increase in translator code size BUG= R=sehr@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1527143003 .
parent 751e27ec
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERING_H #ifndef SUBZERO_SRC_ICETARGETLOWERING_H
#define SUBZERO_SRC_ICETARGETLOWERING_H #define SUBZERO_SRC_ICETARGETLOWERING_H
#include "IceCfgNode.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceInst.h" // for the names of the Inst subtypes #include "IceInst.h" // for the names of the Inst subtypes
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTypes.h" #include "IceTypes.h"
#include <utility>
namespace Ice { namespace Ice {
// UnimplementedError is defined as a macro so that we can get actual line // UnimplementedError is defined as a macro so that we can get actual line
...@@ -72,6 +75,11 @@ public: ...@@ -72,6 +75,11 @@ public:
InstList::iterator getNext() const { return Next; } InstList::iterator getNext() const { return Next; }
InstList::iterator getEnd() const { return End; } InstList::iterator getEnd() const { return End; }
void insert(Inst *Inst); void insert(Inst *Inst);
template <typename Inst, typename... Args> Inst *insert(Args &&... A) {
auto *New = Inst::create(Node->getCfg(), std::forward<Args>(A)...);
insert(New);
return New;
}
Inst *getLastInserted() const; Inst *getLastInserted() const;
void advanceCur() { Cur = Next; } void advanceCur() { Cur = Next; }
void advanceNext() { advanceForward(Next); } void advanceNext() { advanceForward(Next); }
...@@ -370,9 +378,9 @@ protected: ...@@ -370,9 +378,9 @@ protected:
void void
_bundle_lock(InstBundleLock::Option BundleOption = InstBundleLock::Opt_None) { _bundle_lock(InstBundleLock::Option BundleOption = InstBundleLock::Opt_None) {
Context.insert(InstBundleLock::create(Func, BundleOption)); Context.insert<InstBundleLock>(BundleOption);
} }
void _bundle_unlock() { Context.insert(InstBundleUnlock::create(Func)); } void _bundle_unlock() { Context.insert<InstBundleUnlock>(); }
void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); } void _set_dest_redefined() { Context.getLastInserted()->setDestRedefined(); }
bool shouldOptimizeMemIntrins(); bool shouldOptimizeMemIntrins();
......
...@@ -357,11 +357,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -357,11 +357,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
assert(TargetHelper != nullptr); assert(TargetHelper != nullptr);
ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
auto *Call = InstCall::create(Func, 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));
Call->addArg(Instr->getSrc(1)); Call->addArg(Instr->getSrc(1));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -408,7 +407,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -408,7 +407,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
// Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0, // Src0 and Src1 have to be zero-, or signed-extended to i32. For Src0,
// we just insert a InstCast right before the call to the helper. // we just insert a InstCast right before the call to the helper.
Variable *Src0_32 = Func->makeVariable(IceType_i32); Variable *Src0_32 = Func->makeVariable(IceType_i32);
Context.insert(InstCast::create(Func, CastKind, Src0_32, Src0)); Context.insert<InstCast>(CastKind, Src0_32, Src0);
Src0 = Src0_32; Src0 = Src0_32;
// For extending Src1, we will just insert an InstCast if Src1 is not a // For extending Src1, we will just insert an InstCast if Src1 is not a
...@@ -426,20 +425,19 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -426,20 +425,19 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
Src1 = Ctx->getConstantInt32(NewC); Src1 = Ctx->getConstantInt32(NewC);
} else { } else {
Variable *Src1_32 = Func->makeVariable(IceType_i32); Variable *Src1_32 = Func->makeVariable(IceType_i32);
Context.insert(InstCast::create(Func, CastKind, Src1_32, Src1)); Context.insert<InstCast>(CastKind, Src1_32, Src1);
Src1 = Src1_32; Src1 = Src1_32;
} }
} }
assert(TargetHelper != nullptr); assert(TargetHelper != nullptr);
ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem; ARM32HelpersPreamble[TargetHelper] = &TargetARM32::preambleDivRem;
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
assert(Src0->getType() == IceType_i32); assert(Src0->getType() == IceType_i32);
Call->addArg(Src0); Call->addArg(Src0);
assert(Src1->getType() == IceType_i32); assert(Src1->getType() == IceType_i32);
Call->addArg(Src1); Call->addArg(Src1);
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -451,11 +449,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -451,11 +449,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
constexpr SizeT MaxArgs = 2; constexpr SizeT MaxArgs = 2;
Operand *TargetHelper = Ctx->getConstantExternSym( Operand *TargetHelper = Ctx->getConstantExternSym(
DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64); DestTy == IceType_f32 ? H_frem_f32 : H_frem_f64);
auto *Call = InstCall::create(Func, 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));
Call->addArg(Instr->getSrc(1)); Call->addArg(Instr->getSrc(1));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -482,10 +479,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -482,10 +479,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64) Src0IsF32 ? (DestIsSigned ? H_fptosi_f32_i64 : H_fptoui_f32_i64)
: (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64)); : (DestIsSigned ? H_fptosi_f64_i64 : H_fptoui_f64_i64));
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(Src0); Call->addArg(Src0);
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -500,10 +496,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -500,10 +496,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32) DestIsF32 ? (SourceIsSigned ? H_sitofp_i64_f32 : H_uitofp_i64_f32)
: (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64)); : (SourceIsSigned ? H_sitofp_i64_f64 : H_uitofp_i64_f64));
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(Src0); Call->addArg(Src0);
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -523,10 +518,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -523,10 +518,9 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32 isInt32Asserting32Or64(Src0->getType()) ? H_call_ctpop_i32
: H_call_ctpop_i64); : H_call_ctpop_i64);
static constexpr SizeT MaxArgs = 1; static constexpr SizeT MaxArgs = 1;
auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, auto *Call = Context.insert<InstCall>(MaxArgs, Dest, TargetHelper,
NoTailCall, IsTargetHelperCall); NoTailCall, IsTargetHelperCall);
Call->addArg(Src0); Call->addArg(Src0);
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
if (Src0->getType() == IceType_i64) { if (Src0->getType() == IceType_i64) {
ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64; ARM32HelpersPostamble[TargetHelper] = &TargetARM32::postambleCtpop64;
...@@ -537,11 +531,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -537,11 +531,10 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
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->getConstantExternSym(H_call_longjmp);
auto *Call = InstCall::create(Func, 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));
Call->addArg(IntrinsicCall->getArg(1)); Call->addArg(IntrinsicCall->getArg(1));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -551,12 +544,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -551,12 +544,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
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->getConstantExternSym(H_call_memcpy);
auto *Call = InstCall::create(Func, 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));
Call->addArg(IntrinsicCall->getArg(1)); Call->addArg(IntrinsicCall->getArg(1));
Call->addArg(IntrinsicCall->getArg(2)); Call->addArg(IntrinsicCall->getArg(2));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -564,12 +556,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -564,12 +556,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
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->getConstantExternSym(H_call_memmove);
auto *Call = InstCall::create(Func, 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));
Call->addArg(IntrinsicCall->getArg(1)); Call->addArg(IntrinsicCall->getArg(1));
Call->addArg(IntrinsicCall->getArg(2)); Call->addArg(IntrinsicCall->getArg(2));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -579,7 +570,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -579,7 +570,7 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
Operand *ValOp = IntrinsicCall->getArg(1); Operand *ValOp = IntrinsicCall->getArg(1);
assert(ValOp->getType() == IceType_i8); assert(ValOp->getType() == IceType_i8);
Variable *ValExt = Func->makeVariable(stackSlotType()); Variable *ValExt = Func->makeVariable(stackSlotType());
Context.insert(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); Context.insert<InstCast>(InstCast::Zext, ValExt, ValOp);
// Technically, ARM has its own __aeabi_memset, but we can use plain // Technically, ARM has its own __aeabi_memset, but we can use plain
// memset too. The value and size argument need to be flipped if we ever // memset too. The value and size argument need to be flipped if we ever
...@@ -587,12 +578,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -587,12 +578,11 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
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->getConstantExternSym(H_call_memset);
auto *Call = InstCall::create(Func, 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));
Call->addArg(ValExt); Call->addArg(ValExt);
Call->addArg(IntrinsicCall->getArg(2)); Call->addArg(IntrinsicCall->getArg(2));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -602,19 +592,17 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) { ...@@ -602,19 +592,17 @@ void TargetARM32::genTargetHelperCallFor(Inst *Instr) {
} }
static constexpr SizeT MaxArgs = 0; static constexpr SizeT MaxArgs = 0;
Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp); Operand *TargetHelper = Ctx->getConstantExternSym(H_call_read_tp);
auto *Call = InstCall::create(Func, MaxArgs, Dest, TargetHelper, Context.insert<InstCall>(MaxArgs, Dest, TargetHelper, NoTailCall,
NoTailCall, IsTargetHelperCall); IsTargetHelperCall);
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
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->getConstantExternSym(H_call_setjmp);
auto *Call = InstCall::create(Func, 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));
Context.insert(Call);
Instr->setDeleted(); Instr->setDeleted();
return; return;
} }
...@@ -1030,7 +1018,7 @@ void TargetARM32::lowerArguments() { ...@@ -1030,7 +1018,7 @@ void TargetARM32::lowerArguments() {
RegARM32::getI64PairSecondGPRNum(RegNum)); RegARM32::getI64PairSecondGPRNum(RegNum));
} break; } break;
} }
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); Context.insert<InstAssign>(Arg, RegisterArg);
} }
} }
...@@ -1231,7 +1219,7 @@ void TargetARM32::addProlog(CfgNode *Node) { ...@@ -1231,7 +1219,7 @@ void TargetARM32::addProlog(CfgNode *Node) {
Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
_mov(FP, SP); _mov(FP, SP);
// Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode). // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode).
Context.insert(InstFakeUse::create(Func, FP)); Context.insert<InstFakeUse>(FP);
} }
// Align the variables area. SpillAreaPaddingBytes is the size of the region // Align the variables area. SpillAreaPaddingBytes is the size of the region
...@@ -1360,7 +1348,7 @@ void TargetARM32::addEpilog(CfgNode *Node) { ...@@ -1360,7 +1348,7 @@ void TargetARM32::addEpilog(CfgNode *Node) {
// For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
// use of SP before the assignment of SP=FP keeps previous SP adjustments // use of SP before the assignment of SP=FP keeps previous SP adjustments
// from being dead-code eliminated. // from being dead-code eliminated.
Context.insert(InstFakeUse::create(Func, SP)); Context.insert<InstFakeUse>(SP);
Sandboxer(this).reset_sp(FP); Sandboxer(this).reset_sp(FP);
} else { } else {
// add SP, SpillAreaSizeBytes // add SP, SpillAreaSizeBytes
...@@ -1524,7 +1512,7 @@ void TargetARM32::PostLoweringLegalizer::legalizeMov(InstARM32Mov *MovInstr) { ...@@ -1524,7 +1512,7 @@ void TargetARM32::PostLoweringLegalizer::legalizeMov(InstARM32Mov *MovInstr) {
.str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset), .str(SrcR, createMemOperand(DestTy, StackOrFrameReg, Offset),
MovInstr->getPredicate()); MovInstr->getPredicate());
// _str() does not have a Dest, so we add a fake-def(Dest). // _str() does not have a Dest, so we add a fake-def(Dest).
Target->Context.insert(InstFakeDef::create(Target->Func, Dest)); Target->Context.insert<InstFakeDef>(Dest);
Legalized = true; Legalized = true;
} else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
if (Var->isRematerializable()) { if (Var->isRematerializable()) {
...@@ -1899,7 +1887,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) { ...@@ -1899,7 +1887,7 @@ void TargetARM32::lowerAlloca(const InstAlloca *Inst) {
// value to Dest, as Dest is rematerializable. // value to Dest, as Dest is rematerializable.
assert(Dest->isRematerializable()); assert(Dest->isRematerializable());
FixedAllocaSizeBytes += Value; FixedAllocaSizeBytes += Value;
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
return; return;
} }
...@@ -1944,7 +1932,7 @@ void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) { ...@@ -1944,7 +1932,7 @@ void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) {
Operand *ShAmtImm = shAmtImm(32 - getScalarIntBitWidth(Ty)); Operand *ShAmtImm = shAmtImm(32 - getScalarIntBitWidth(Ty));
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_lsls(T, SrcLoReg, ShAmtImm); _lsls(T, SrcLoReg, ShAmtImm);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} break; } break;
case IceType_i32: { case IceType_i32: {
_tst(SrcLoReg, SrcLoReg); _tst(SrcLoReg, SrcLoReg);
...@@ -1955,7 +1943,7 @@ void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) { ...@@ -1955,7 +1943,7 @@ void TargetARM32::div0Check(Type Ty, Operand *SrcLo, Operand *SrcHi) {
_orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex)); _orrs(T, SrcLoReg, legalize(SrcHi, Legal_Reg | Legal_Flex));
// T isn't going to be used, but we need the side-effect of setting flags // T isn't going to be used, but we need the side-effect of setting flags
// from this operation. // from this operation.
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} }
} }
auto *Label = InstARM32Label::create(Func, this); auto *Label = InstARM32Label::create(Func, this);
...@@ -2711,7 +2699,7 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -2711,7 +2699,7 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
Variable *Dest = Instr->getDest(); Variable *Dest = Instr->getDest();
if (Dest->isRematerializable()) { if (Dest->isRematerializable()) {
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
return; return;
} }
...@@ -2731,7 +2719,7 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -2731,7 +2719,7 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
if (isVectorType(DestTy)) { if (isVectorType(DestTy)) {
// Add a fake def to keep liveness consistent in the meantime. // Add a fake def to keep liveness consistent in the meantime.
Variable *T = makeReg(DestTy); Variable *T = makeReg(DestTy);
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
...@@ -3063,7 +3051,7 @@ void TargetARM32::lowerAssign(const InstAssign *Inst) { ...@@ -3063,7 +3051,7 @@ void TargetARM32::lowerAssign(const InstAssign *Inst) {
Variable *Dest = Inst->getDest(); Variable *Dest = Inst->getDest();
if (Dest->isRematerializable()) { if (Dest->isRematerializable()) {
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
return; return;
} }
...@@ -3367,29 +3355,28 @@ void TargetARM32::lowerCall(const InstCall *Instr) { ...@@ -3367,29 +3355,28 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
// Copy arguments to be passed in registers to the appropriate registers. // Copy arguments to be passed in registers to the appropriate registers.
for (auto &FPArg : FPArgs) { for (auto &FPArg : FPArgs) {
Variable *Reg = legalizeToReg(FPArg.first, FPArg.second); Variable *Reg = legalizeToReg(FPArg.first, FPArg.second);
Context.insert(InstFakeUse::create(Func, Reg)); Context.insert<InstFakeUse>(Reg);
} }
for (auto &GPRArg : GPRArgs) { for (auto &GPRArg : GPRArgs) {
Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second); Variable *Reg = legalizeToReg(GPRArg.first, GPRArg.second);
// Generate a FakeUse of register arguments so that they do not get dead // Generate a FakeUse of register arguments so that they do not get dead
// code eliminated as a result of the FakeKill of scratch registers after // code eliminated as a result of the FakeKill of scratch registers after
// the call. // the call.
Context.insert(InstFakeUse::create(Func, Reg)); Context.insert<InstFakeUse>(Reg);
} }
InstARM32Call *NewCall = InstARM32Call *NewCall =
Sandboxer(this, InstBundleLock::Opt_AlignToEnd).bl(ReturnReg, CallTarget); Sandboxer(this, InstBundleLock::Opt_AlignToEnd).bl(ReturnReg, CallTarget);
if (ReturnRegHi) if (ReturnRegHi)
Context.insert(InstFakeDef::create(Func, ReturnRegHi)); Context.insert<InstFakeDef>(ReturnRegHi);
// Insert a register-kill pseudo instruction. // Insert a register-kill pseudo instruction.
Context.insert(InstFakeKill::create(Func, NewCall)); Context.insert<InstFakeKill>(NewCall);
// Generate a FakeUse to keep the call live if necessary. // Generate a FakeUse to keep the call live if necessary.
if (Instr->hasSideEffects() && ReturnReg) { if (Instr->hasSideEffects() && ReturnReg) {
Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); Context.insert<InstFakeUse>(ReturnReg);
Context.insert(FakeUse);
} }
if (Dest != nullptr) { if (Dest != nullptr) {
...@@ -3440,7 +3427,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3440,7 +3427,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case InstCast::Sext: { case InstCast::Sext: {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} else if (Dest->getType() == IceType_i64) { } else if (Dest->getType() == IceType_i64) {
...@@ -3488,7 +3475,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3488,7 +3475,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case InstCast::Zext: { case InstCast::Zext: {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} else if (Dest->getType() == IceType_i64) { } else if (Dest->getType() == IceType_i64) {
...@@ -3544,7 +3531,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3544,7 +3531,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case InstCast::Trunc: { case InstCast::Trunc: {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} else { } else {
...@@ -3567,7 +3554,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3567,7 +3554,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
const bool IsTrunc = CastKind == InstCast::Fptrunc; const bool IsTrunc = CastKind == InstCast::Fptrunc;
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
break; break;
...@@ -3584,7 +3571,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3584,7 +3571,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case InstCast::Fptoui: { case InstCast::Fptoui: {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
break; break;
...@@ -3623,7 +3610,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3623,7 +3610,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case InstCast::Uitofp: { case InstCast::Uitofp: {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
break; break;
...@@ -3700,8 +3687,8 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3700,8 +3687,8 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
configureBitcastTemporary(T); configureBitcastTemporary(T);
Variable *Src0R = legalizeToReg(Src0); Variable *Src0R = legalizeToReg(Src0);
_mov(T, Src0R); _mov(T, Src0R);
Context.insert(InstFakeUse::create(Func, T->getHi())); Context.insert<InstFakeUse>(T->getHi());
Context.insert(InstFakeUse::create(Func, T->getLo())); Context.insert<InstFakeUse>(T->getLo());
lowerAssign(InstAssign::create(Func, Dest, T)); lowerAssign(InstAssign::create(Func, Dest, T));
break; break;
} }
...@@ -3729,7 +3716,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) { ...@@ -3729,7 +3716,7 @@ void TargetARM32::lowerCast(const InstCast *Inst) {
case IceType_v4i32: { case IceType_v4i32: {
// avoid liveness errors // avoid liveness errors
Variable *T = makeReg(DestType); Variable *T = makeReg(DestType);
Context.insert(InstFakeDef::create(Func, T, legalizeToReg(Src0))); Context.insert<InstFakeDef>(T, legalizeToReg(Src0));
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
break; break;
...@@ -3744,7 +3731,7 @@ void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) { ...@@ -3744,7 +3731,7 @@ void TargetARM32::lowerExtractElement(const InstExtractElement *Inst) {
Variable *Dest = Inst->getDest(); Variable *Dest = Inst->getDest();
Type DestType = Dest->getType(); Type DestType = Dest->getType();
Variable *T = makeReg(DestType); Variable *T = makeReg(DestType);
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
...@@ -3826,7 +3813,7 @@ void TargetARM32::lowerFcmp(const InstFcmp *Instr) { ...@@ -3826,7 +3813,7 @@ void TargetARM32::lowerFcmp(const InstFcmp *Instr) {
Variable *Dest = Instr->getDest(); Variable *Dest = Instr->getDest();
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
...@@ -3884,7 +3871,7 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -3884,7 +3871,7 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
Variable *Src0LoR = SrcsLo.src0R(this); Variable *Src0LoR = SrcsLo.src0R(this);
Variable *Src0HiR = SrcsHi.src0R(this); Variable *Src0HiR = SrcsHi.src0R(this);
_orrs(T, Src0LoR, Src0HiR); _orrs(T, Src0LoR, Src0HiR);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
return CondWhenTrue(TableIcmp64[Index].C1); return CondWhenTrue(TableIcmp64[Index].C1);
} }
...@@ -3899,29 +3886,29 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -3899,29 +3886,29 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
if (TableIcmp64[Index].IsSigned) { if (TableIcmp64[Index].IsSigned) {
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_rsbs(T, Src0RLo, Src1RFLo); _rsbs(T, Src0RLo, Src1RFLo);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
T = makeReg(IceType_i32); T = makeReg(IceType_i32);
_rscs(T, Src0RHi, Src1RFHi); _rscs(T, Src0RHi, Src1RFHi);
// We need to add a FakeUse here because liveness gets mad at us (Def // We need to add a FakeUse here because liveness gets mad at us (Def
// without Use.) Note that flag-setting instructions are considered to // without Use.) Note that flag-setting instructions are considered to
// have side effects and, therefore, are not DCE'ed. // have side effects and, therefore, are not DCE'ed.
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} else { } else {
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_rsbs(T, Src0RHi, Src1RFHi); _rsbs(T, Src0RHi, Src1RFHi);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
T = makeReg(IceType_i32); T = makeReg(IceType_i32);
_rsbs(T, Src0RLo, Src1RFLo, CondARM32::EQ); _rsbs(T, Src0RLo, Src1RFLo, CondARM32::EQ);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} }
} else { } else {
if (TableIcmp64[Index].IsSigned) { if (TableIcmp64[Index].IsSigned) {
_cmp(Src0RLo, Src1RFLo); _cmp(Src0RLo, Src1RFLo);
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_sbcs(T, Src0RHi, Src1RFHi); _sbcs(T, Src0RHi, Src1RFHi);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} else { } else {
_cmp(Src0RHi, Src1RFHi); _cmp(Src0RHi, Src1RFHi);
_cmp(Src0RLo, Src1RFLo, CondARM32::EQ); _cmp(Src0RLo, Src1RFLo, CondARM32::EQ);
...@@ -3980,7 +3967,7 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -3980,7 +3967,7 @@ TargetARM32::lowerInt64IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
_sbcs(ScratchReg, Src0RHi, Src1RFHi); _sbcs(ScratchReg, Src0RHi, Src1RFHi);
// ScratchReg isn't going to be used, but we need the side-effect of // ScratchReg isn't going to be used, but we need the side-effect of
// setting flags from this operation. // setting flags from this operation.
Context.insert(InstFakeUse::create(Func, ScratchReg)); Context.insert<InstFakeUse>(ScratchReg);
} else { } else {
_cmp(Src0RHi, Src1RFHi); _cmp(Src0RHi, Src1RFHi);
_cmp(Src0RLo, Src1RFLo, CondARM32::EQ); _cmp(Src0RLo, Src1RFLo, CondARM32::EQ);
...@@ -4020,7 +4007,7 @@ TargetARM32::lowerInt32IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -4020,7 +4007,7 @@ TargetARM32::lowerInt32IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
} else { } else {
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_rsbs(T, Src0R, Src1RF); _rsbs(T, Src0R, Src1RF);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} }
return CondWhenTrue(getIcmp32Mapping(Condition)); return CondWhenTrue(getIcmp32Mapping(Condition));
} }
...@@ -4049,7 +4036,7 @@ TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -4049,7 +4036,7 @@ TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
Operand *ShAmtImm = shAmtImm(ShAmt); Operand *ShAmtImm = shAmtImm(ShAmt);
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_lsls(T, Srcs.src0R(this), ShAmtImm); _lsls(T, Srcs.src0R(this), ShAmtImm);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
return CondWhenTrue(getIcmp32Mapping(Condition)); return CondWhenTrue(getIcmp32Mapping(Condition));
} }
...@@ -4065,7 +4052,7 @@ TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0, ...@@ -4065,7 +4052,7 @@ TargetARM32::lowerInt8AndInt16IcmpCond(InstIcmp::ICond Condition, Operand *Src0,
} else { } else {
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_rsbs(T, ConstR, NonConstF); _rsbs(T, ConstR, NonConstF);
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
} }
return CondWhenTrue(getIcmp32Mapping(Condition)); return CondWhenTrue(getIcmp32Mapping(Condition));
} }
...@@ -4125,7 +4112,7 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) { ...@@ -4125,7 +4112,7 @@ void TargetARM32::lowerIcmp(const InstIcmp *Inst) {
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
...@@ -4219,7 +4206,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, ...@@ -4219,7 +4206,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
} }
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, Value)); Context.insert<InstFakeDef>(Value);
} }
lowerAssign(InstAssign::create(Func, Value, Val)); lowerAssign(InstAssign::create(Func, Value, Val));
...@@ -4230,7 +4217,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, ...@@ -4230,7 +4217,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
Context.insert(Retry); Context.insert(Retry);
Mem = formMemoryOperand(PtrVar, DestTy); Mem = formMemoryOperand(PtrVar, DestTy);
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, ValueReg, Value)); Context.insert<InstFakeDef>(ValueReg, Value);
} }
lowerAssign(InstAssign::create(Func, ValueReg, Value)); lowerAssign(InstAssign::create(Func, ValueReg, Value));
if (DestTy == IceType_i8 || DestTy == IceType_i16) { if (DestTy == IceType_i8 || DestTy == IceType_i16) {
...@@ -4239,7 +4226,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, ...@@ -4239,7 +4226,7 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
_ldrex(PtrContentsReg, Mem); _ldrex(PtrContentsReg, Mem);
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, TmpReg, ValueReg)); Context.insert<InstFakeDef>(TmpReg, ValueReg);
} }
switch (Operation) { switch (Operation) {
default: default:
...@@ -4293,12 +4280,12 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, ...@@ -4293,12 +4280,12 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
// The following fake-uses ensure that Subzero will not clobber them in the // The following fake-uses ensure that Subzero will not clobber them in the
// load-linked/store-conditional loop above. We might have to spill them, but // load-linked/store-conditional loop above. We might have to spill them, but
// spilling is preferable over incorrect behavior. // spilling is preferable over incorrect behavior.
Context.insert(InstFakeUse::create(Func, PtrVar)); Context.insert<InstFakeUse>(PtrVar);
if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) { if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) {
Context.insert(InstFakeUse::create(Func, Value64->getHi())); Context.insert<InstFakeUse>(Value64->getHi());
Context.insert(InstFakeUse::create(Func, Value64->getLo())); Context.insert<InstFakeUse>(Value64->getLo());
} else { } else {
Context.insert(InstFakeUse::create(Func, Value)); Context.insert<InstFakeUse>(Value);
} }
_dmb(); _dmb();
if (DestTy == IceType_i8 || DestTy == IceType_i16) { if (DestTy == IceType_i8 || DestTy == IceType_i16) {
...@@ -4306,14 +4293,14 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation, ...@@ -4306,14 +4293,14 @@ void TargetARM32::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
} }
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeUse::create(Func, PtrContentsReg)); Context.insert<InstFakeUse>(PtrContentsReg);
} }
lowerAssign(InstAssign::create(Func, Dest, PtrContentsReg)); lowerAssign(InstAssign::create(Func, Dest, PtrContentsReg));
if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) { if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
Context.insert(InstFakeUse::create(Func, Dest64->getLo())); Context.insert<InstFakeUse>(Dest64->getLo());
Context.insert(InstFakeUse::create(Func, Dest64->getHi())); Context.insert<InstFakeUse>(Dest64->getHi());
} else { } else {
Context.insert(InstFakeUse::create(Func, Dest)); Context.insert<InstFakeUse>(Dest);
} }
} }
...@@ -4391,8 +4378,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4391,8 +4378,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
// Make sure the atomic load isn't elided when unused, by adding a FakeUse. // Make sure the atomic load isn't elided when unused, by adding a FakeUse.
// Since lowerLoad may fuse the load w/ an arithmetic instruction, insert // Since lowerLoad may fuse the load w/ an arithmetic instruction, insert
// the FakeUse on the last-inserted instruction's dest. // the FakeUse on the last-inserted instruction's dest.
Context.insert( Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
return; return;
} }
case Intrinsics::AtomicStore: { case Intrinsics::AtomicStore: {
...@@ -4438,21 +4424,20 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4438,21 +4424,20 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
lowerAssign(InstAssign::create(Func, AddrVar, Addr)); lowerAssign(InstAssign::create(Func, AddrVar, Addr));
Context.insert(Retry); Context.insert(Retry);
Context.insert(InstFakeDef::create(Func, NewReg)); Context.insert<InstFakeDef>(NewReg);
lowerAssign(InstAssign::create(Func, NewReg, ValueVar)); lowerAssign(InstAssign::create(Func, NewReg, ValueVar));
Mem = formMemoryOperand(AddrVar, IceType_i64); Mem = formMemoryOperand(AddrVar, IceType_i64);
_ldrex(Tmp, Mem); _ldrex(Tmp, Mem);
// This fake-use both prevents the ldrex from being dead-code eliminated, // This fake-use both prevents the ldrex from being dead-code eliminated,
// while also keeping liveness happy about all defs being used. // while also keeping liveness happy about all defs being used.
Context.insert( Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
_strex(Success, NewReg, Mem); _strex(Success, NewReg, Mem);
_cmp(Success, _0); _cmp(Success, _0);
_br(Retry, CondARM32::NE); _br(Retry, CondARM32::NE);
Context.insert(InstFakeUse::create(Func, ValueVar->getLo())); Context.insert<InstFakeUse>(ValueVar->getLo());
Context.insert(InstFakeUse::create(Func, ValueVar->getHi())); Context.insert<InstFakeUse>(ValueVar->getHi());
Context.insert(InstFakeUse::create(Func, AddrVar)); Context.insert<InstFakeUse>(AddrVar);
_dmb(); _dmb();
return; return;
} }
...@@ -4550,35 +4535,34 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4550,35 +4535,34 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Mem = formMemoryOperand(Instr->getArg(0), DestTy); Mem = formMemoryOperand(Instr->getArg(0), DestTy);
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, Expected)); Context.insert<InstFakeDef>(Expected);
} }
lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1))); lowerAssign(InstAssign::create(Func, Expected, Instr->getArg(1)));
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, New)); Context.insert<InstFakeDef>(New);
} }
lowerAssign(InstAssign::create(Func, New, Instr->getArg(2))); lowerAssign(InstAssign::create(Func, New, Instr->getArg(2)));
_dmb(); _dmb();
Context.insert(Retry); Context.insert(Retry);
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, ExpectedReg, Expected)); Context.insert<InstFakeDef>(ExpectedReg, Expected);
} }
lowerAssign(InstAssign::create(Func, ExpectedReg, Expected)); lowerAssign(InstAssign::create(Func, ExpectedReg, Expected));
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Context.insert(InstFakeDef::create(Func, NewReg, New)); Context.insert<InstFakeDef>(NewReg, New);
} }
lowerAssign(InstAssign::create(Func, NewReg, New)); lowerAssign(InstAssign::create(Func, NewReg, New));
_ldrex(TmpReg, Mem); _ldrex(TmpReg, Mem);
Context.insert( Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg); auto *TmpReg64 = llvm::cast<Variable64On32>(TmpReg);
auto *ExpectedReg64 = llvm::cast<Variable64On32>(ExpectedReg); auto *ExpectedReg64 = llvm::cast<Variable64On32>(ExpectedReg);
// lowerAssign above has added fake-defs for TmpReg and ExpectedReg. Let's // lowerAssign above has added fake-defs for TmpReg and ExpectedReg. Let's
// keep liveness happy, shall we? // keep liveness happy, shall we?
Context.insert(InstFakeUse::create(Func, TmpReg)); Context.insert<InstFakeUse>(TmpReg);
Context.insert(InstFakeUse::create(Func, ExpectedReg)); Context.insert<InstFakeUse>(ExpectedReg);
_cmp(TmpReg64->getHi(), ExpectedReg64->getHi()); _cmp(TmpReg64->getHi(), ExpectedReg64->getHi());
_cmp(TmpReg64->getLo(), ExpectedReg64->getLo(), CondARM32::EQ); _cmp(TmpReg64->getLo(), ExpectedReg64->getLo(), CondARM32::EQ);
} else { } else {
...@@ -4590,9 +4574,8 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4590,9 +4574,8 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *Expected64 = llvm::cast<Variable64On32>(Expected); auto *Expected64 = llvm::cast<Variable64On32>(Expected);
_mov_redefined(Expected64->getHi(), TmpReg64->getHi(), CondARM32::NE); _mov_redefined(Expected64->getHi(), TmpReg64->getHi(), CondARM32::NE);
_mov_redefined(Expected64->getLo(), TmpReg64->getLo(), CondARM32::NE); _mov_redefined(Expected64->getLo(), TmpReg64->getLo(), CondARM32::NE);
auto *FakeDef = InstFakeDef::create(Func, Expected, TmpReg); Context.insert<InstFakeDef>(Expected, TmpReg);
Context.insert(FakeDef); _set_dest_redefined();
FakeDef->setDestRedefined();
} else { } else {
_mov_redefined(Expected, TmpReg, CondARM32::NE); _mov_redefined(Expected, TmpReg, CondARM32::NE);
} }
...@@ -4600,12 +4583,12 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4600,12 +4583,12 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_br(Retry, CondARM32::NE); _br(Retry, CondARM32::NE);
_dmb(); _dmb();
lowerAssign(InstAssign::create(Func, Dest, Expected)); lowerAssign(InstAssign::create(Func, Dest, Expected));
Context.insert(InstFakeUse::create(Func, Expected)); Context.insert<InstFakeUse>(Expected);
if (auto *New64 = llvm::dyn_cast<Variable64On32>(New)) { if (auto *New64 = llvm::dyn_cast<Variable64On32>(New)) {
Context.insert(InstFakeUse::create(Func, New64->getLo())); Context.insert<InstFakeUse>(New64->getLo());
Context.insert(InstFakeUse::create(Func, New64->getHi())); Context.insert<InstFakeUse>(New64->getHi());
} else { } else {
Context.insert(InstFakeUse::create(Func, New)); Context.insert<InstFakeUse>(New);
} }
return; return;
} }
...@@ -4697,7 +4680,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4697,7 +4680,7 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Variable *T = makeReg(DestTy); Variable *T = makeReg(DestTy);
if (isVectorType(DestTy)) { if (isVectorType(DestTy)) {
// Add a fake def to keep liveness consistent in the meantime. // Add a fake def to keep liveness consistent in the meantime.
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
...@@ -5162,8 +5145,7 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func, ...@@ -5162,8 +5145,7 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func,
// //
const Type PointerType = getPointerType(); const Type PointerType = getPointerType();
BaseVar = makeReg(PointerType); BaseVar = makeReg(PointerType);
Context.insert( Context.insert<InstAssign>(BaseVar, Ctx->getConstantInt32(OffsetImm));
InstAssign::create(Func, BaseVar, Ctx->getConstantInt32(OffsetImm)));
OffsetImm = 0; OffsetImm = 0;
} else if (OffsetImm != 0) { } else if (OffsetImm != 0) {
// ARM Ldr/Str instructions have limited range immediates. The formation // ARM Ldr/Str instructions have limited range immediates. The formation
...@@ -5194,8 +5176,8 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func, ...@@ -5194,8 +5176,8 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func,
// use of [T, Offset {, LSL amount}] // use of [T, Offset {, LSL amount}]
const Type PointerType = getPointerType(); const Type PointerType = getPointerType();
Variable *T = makeReg(PointerType); Variable *T = makeReg(PointerType);
Context.insert(InstArithmetic::create( Context.insert<InstArithmetic>(Op, T, BaseVar,
Func, Op, T, BaseVar, Ctx->getConstantInt32(PositiveOffset))); Ctx->getConstantInt32(PositiveOffset));
BaseVar = T; BaseVar = T;
OffsetImm = 0; OffsetImm = 0;
} }
...@@ -5209,7 +5191,7 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func, ...@@ -5209,7 +5191,7 @@ OperandARM32Mem *TargetARM32::formAddressingMode(Type Ty, Cfg *Func,
if (OffsetReg != nullptr) { if (OffsetReg != nullptr) {
Variable *OffsetR = makeReg(getPointerType()); Variable *OffsetR = makeReg(getPointerType());
Context.insert(InstAssign::create(Func, OffsetR, OffsetReg)); Context.insert<InstAssign>(OffsetR, OffsetReg);
return OperandARM32Mem::create(Func, Ty, BaseVar, OffsetR, ShiftKind, return OperandARM32Mem::create(Func, Ty, BaseVar, OffsetR, ShiftKind,
OffsetRegShamt); OffsetRegShamt);
} }
...@@ -5227,7 +5209,7 @@ void TargetARM32::doAddressOptLoad() { ...@@ -5227,7 +5209,7 @@ void TargetARM32::doAddressOptLoad() {
if (OperandARM32Mem *Mem = if (OperandARM32Mem *Mem =
formAddressingMode(Dest->getType(), Func, Instr, Addr)) { formAddressingMode(Dest->getType(), Func, Instr, Addr)) {
Instr->setDeleted(); Instr->setDeleted();
Context.insert(InstLoad::create(Func, Dest, Mem)); Context.insert<InstLoad>(Dest, Mem);
} }
} }
...@@ -5253,7 +5235,7 @@ void TargetARM32::lowerRet(const InstRet *Inst) { ...@@ -5253,7 +5235,7 @@ void TargetARM32::lowerRet(const InstRet *Inst) {
Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0); Variable *R0 = legalizeToReg(loOperand(Src0), RegARM32::Reg_r0);
Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1); Variable *R1 = legalizeToReg(hiOperand(Src0), RegARM32::Reg_r1);
Reg = R0; Reg = R0;
Context.insert(InstFakeUse::create(Func, R1)); Context.insert<InstFakeUse>(R1);
} else if (Ty == IceType_f32) { } else if (Ty == IceType_f32) {
Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0); Variable *S0 = legalizeToReg(Src0, RegARM32::Reg_s0);
Reg = S0; Reg = S0;
...@@ -5280,7 +5262,7 @@ void TargetARM32::lowerRet(const InstRet *Inst) { ...@@ -5280,7 +5262,7 @@ void TargetARM32::lowerRet(const InstRet *Inst) {
// TODO: Are there more places where the fake use should be inserted? E.g. // TODO: Are there more places where the fake use should be inserted? E.g.
// "void f(int n){while(1) g(n);}" may not have a ret instruction. // "void f(int n){while(1) g(n);}" may not have a ret instruction.
Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = getPhysicalRegister(RegARM32::Reg_sp);
Context.insert(InstFakeUse::create(Func, SP)); Context.insert<InstFakeUse>(SP);
} }
void TargetARM32::lowerSelect(const InstSelect *Inst) { void TargetARM32::lowerSelect(const InstSelect *Inst) {
...@@ -5292,7 +5274,7 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) { ...@@ -5292,7 +5274,7 @@ void TargetARM32::lowerSelect(const InstSelect *Inst) {
if (isVectorType(DestTy)) { if (isVectorType(DestTy)) {
Variable *T = makeReg(DestTy); Variable *T = makeReg(DestTy);
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_mov(Dest, T); _mov(Dest, T);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
...@@ -5327,7 +5309,7 @@ void TargetARM32::doAddressOptStore() { ...@@ -5327,7 +5309,7 @@ void TargetARM32::doAddressOptStore() {
if (OperandARM32Mem *Mem = if (OperandARM32Mem *Mem =
formAddressingMode(Src->getType(), Func, Instr, Addr)) { formAddressingMode(Src->getType(), Func, Instr, Addr)) {
Instr->setDeleted(); Instr->setDeleted();
Context.insert(InstStore::create(Func, Src, Mem)); Context.insert<InstStore>(Src, Mem);
} }
} }
...@@ -5385,7 +5367,7 @@ void TargetARM32::prelowerPhis() { ...@@ -5385,7 +5367,7 @@ void TargetARM32::prelowerPhis() {
Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) {
Variable *Reg = makeReg(Ty, RegNum); Variable *Reg = makeReg(Ty, RegNum);
Context.insert(InstFakeDef::create(Func, Reg)); Context.insert<InstFakeDef>(Reg);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return Reg; return Reg;
} }
...@@ -5559,7 +5541,7 @@ Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, ...@@ -5559,7 +5541,7 @@ Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
// Use T = T ^ T to load a 64-bit fp zero. This does not work for f32 // Use T = T ^ T to load a 64-bit fp zero. This does not work for f32
// because ARM does not have a veor instruction with S registers. // because ARM does not have a veor instruction with S registers.
Variable *T = makeReg(IceType_f64, RegNum); Variable *T = makeReg(IceType_f64, RegNum);
Context.insert(InstFakeDef::create(Func, T)); Context.insert<InstFakeDef>(T);
_veor(T, T, T); _veor(T, T, T);
return T; return T;
} }
...@@ -6187,9 +6169,7 @@ InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg, ...@@ -6187,9 +6169,7 @@ InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg,
indirectBranchBicMask(Target->Func)); indirectBranchBicMask(Target->Func));
} }
} }
auto *Call = InstARM32Call::create(Target->Func, ReturnReg, CallTarget); return Target->Context.insert<InstARM32Call>(ReturnReg, CallTarget);
Target->Context.insert(Call);
return Call;
} }
void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem, void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem,
......
...@@ -277,60 +277,56 @@ protected: ...@@ -277,60 +277,56 @@ protected:
// assembly as practical. // assembly as practical.
void _add(Variable *Dest, Variable *Src0, Operand *Src1, void _add(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Add>(Dest, Src0, Src1, Pred);
} }
void _adds(Variable *Dest, Variable *Src0, Operand *Src1, void _adds(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Add>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Add::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _adc(Variable *Dest, Variable *Src0, Operand *Src1, void _adc(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Adc::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Adc>(Dest, Src0, Src1, Pred);
} }
void _and(Variable *Dest, Variable *Src0, Operand *Src1, void _and(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32And::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32And>(Dest, Src0, Src1, Pred);
} }
void _asr(Variable *Dest, Variable *Src0, Operand *Src1, void _asr(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Asr::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Asr>(Dest, Src0, Src1, Pred);
} }
void _bic(Variable *Dest, Variable *Src0, Operand *Src1, void _bic(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Bic::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Bic>(Dest, Src0, Src1, Pred);
} }
void _br(CfgNode *TargetTrue, CfgNode *TargetFalse, void _br(CfgNode *TargetTrue, CfgNode *TargetFalse,
CondARM32::Cond Condition) { CondARM32::Cond Condition) {
Context.insert( Context.insert<InstARM32Br>(TargetTrue, TargetFalse, Condition);
InstARM32Br::create(Func, TargetTrue, TargetFalse, Condition));
}
void _br(CfgNode *Target) {
Context.insert(InstARM32Br::create(Func, Target));
} }
void _br(CfgNode *Target) { Context.insert<InstARM32Br>(Target); }
void _br(CfgNode *Target, CondARM32::Cond Condition) { void _br(CfgNode *Target, CondARM32::Cond Condition) {
Context.insert(InstARM32Br::create(Func, Target, Condition)); Context.insert<InstARM32Br>(Target, Condition);
} }
void _br(InstARM32Label *Label, CondARM32::Cond Condition) { void _br(InstARM32Label *Label, CondARM32::Cond Condition) {
Context.insert(InstARM32Br::create(Func, Label, Condition)); Context.insert<InstARM32Br>(Label, Condition);
} }
void _cmn(Variable *Src0, Operand *Src1, void _cmn(Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Cmn::create(Func, Src0, Src1, Pred)); Context.insert<InstARM32Cmn>(Src0, Src1, Pred);
} }
void _cmp(Variable *Src0, Operand *Src1, void _cmp(Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Cmp::create(Func, Src0, Src1, Pred)); Context.insert<InstARM32Cmp>(Src0, Src1, Pred);
} }
void _clz(Variable *Dest, Variable *Src0, void _clz(Variable *Dest, Variable *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Clz::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Clz>(Dest, Src0, Pred);
} }
void _dmb() { Context.insert(InstARM32Dmb::create(Func)); } void _dmb() { Context.insert<InstARM32Dmb>(); }
void _eor(Variable *Dest, Variable *Src0, Operand *Src1, void _eor(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Eor>(Dest, Src0, Src1, Pred);
} }
/// _ldr, for all your memory to Variable data moves. It handles all types /// _ldr, for all your memory to Variable data moves. It handles all types
/// (integer, floating point, and vectors.) Addr needs to be valid for Dest's /// (integer, floating point, and vectors.) Addr needs to be valid for Dest's
...@@ -338,37 +334,36 @@ protected: ...@@ -338,37 +334,36 @@ protected:
/// loads.) /// loads.)
void _ldr(Variable *Dest, OperandARM32Mem *Addr, void _ldr(Variable *Dest, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred)); Context.insert<InstARM32Ldr>(Dest, Addr, Pred);
} }
void _ldrex(Variable *Dest, OperandARM32Mem *Addr, void _ldrex(Variable *Dest, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Ldrex::create(Func, Dest, Addr, Pred)); Context.insert<InstARM32Ldrex>(Dest, Addr, Pred);
if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) { if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
Context.insert(InstFakeDef::create(Func, Dest64->getLo(), Dest)); Context.insert<InstFakeDef>(Dest64->getLo(), Dest);
Context.insert(InstFakeDef::create(Func, Dest64->getHi(), Dest)); Context.insert<InstFakeDef>(Dest64->getHi(), Dest);
} }
} }
void _lsl(Variable *Dest, Variable *Src0, Operand *Src1, void _lsl(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Lsl>(Dest, Src0, Src1, Pred);
} }
void _lsls(Variable *Dest, Variable *Src0, Operand *Src1, void _lsls(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Lsl>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, void _lsr(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Lsr>(Dest, Src0, Src1, Pred);
} }
void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); Context.insert<InstARM32Mla>(Dest, Src0, Src1, Acc, Pred);
} }
void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); Context.insert<InstARM32Mls>(Dest, Src0, Src1, Acc, Pred);
} }
/// _mov, for all your Variable to Variable data movement needs. It handles /// _mov, for all your Variable to Variable data movement needs. It handles
/// all types (integer, floating point, and vectors), as well as moves between /// all types (integer, floating point, and vectors), as well as moves between
...@@ -382,27 +377,25 @@ protected: ...@@ -382,27 +377,25 @@ protected:
// is nullptr. // is nullptr.
assert(Dest != nullptr); assert(Dest != nullptr);
assert(!llvm::isa<OperandARM32Mem>(Src0)); assert(!llvm::isa<OperandARM32Mem>(Src0));
auto *Instr = InstARM32Mov::create(Func, Dest, Src0, Pred); auto *Instr = Context.insert<InstARM32Mov>(Dest, Src0, Pred);
Context.insert(Instr);
if (Instr->isMultiDest()) { if (Instr->isMultiDest()) {
// If Instr is multi-dest, then Dest must be a Variable64On32. We add a // If Instr is multi-dest, then Dest must be a Variable64On32. We add a
// fake-def for Instr.DestHi here. // fake-def for Instr.DestHi here.
assert(llvm::isa<Variable64On32>(Dest)); assert(llvm::isa<Variable64On32>(Dest));
Context.insert(InstFakeDef::create(Func, Instr->getDestHi())); Context.insert<InstFakeDef>(Instr->getDestHi());
} }
} }
void _mov_redefined(Variable *Dest, Operand *Src0, void _mov_redefined(Variable *Dest, Operand *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
auto *Instr = InstARM32Mov::create(Func, Dest, Src0, Pred); auto *Instr = Context.insert<InstARM32Mov>(Dest, Src0, Pred);
Instr->setDestRedefined(); Instr->setDestRedefined();
Context.insert(Instr);
if (Instr->isMultiDest()) { if (Instr->isMultiDest()) {
// If Instr is multi-dest, then Dest must be a Variable64On32. We add a // If Instr is multi-dest, then Dest must be a Variable64On32. We add a
// fake-def for Instr.DestHi here. // fake-def for Instr.DestHi here.
assert(llvm::isa<Variable64On32>(Dest)); assert(llvm::isa<Variable64On32>(Dest));
Context.insert(InstFakeDef::create(Func, Instr->getDestHi())); Context.insert<InstFakeDef>(Instr->getDestHi());
} }
} }
...@@ -637,182 +630,173 @@ protected: ...@@ -637,182 +630,173 @@ protected:
/// an upper16 relocation). /// an upper16 relocation).
void _movt(Variable *Dest, Operand *Src0, void _movt(Variable *Dest, Operand *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Movt::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Movt>(Dest, Src0, Pred);
} }
void _movw(Variable *Dest, Operand *Src0, void _movw(Variable *Dest, Operand *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Movw::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Movw>(Dest, Src0, Pred);
} }
void _mul(Variable *Dest, Variable *Src0, Variable *Src1, void _mul(Variable *Dest, Variable *Src0, Variable *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Mul::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Mul>(Dest, Src0, Src1, Pred);
} }
void _mvn(Variable *Dest, Operand *Src0, void _mvn(Variable *Dest, Operand *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Mvn::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Mvn>(Dest, Src0, Pred);
} }
void _orr(Variable *Dest, Variable *Src0, Operand *Src1, void _orr(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Orr::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Orr>(Dest, Src0, Src1, Pred);
} }
void _orrs(Variable *Dest, Variable *Src0, Operand *Src1, void _orrs(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Orr>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Orr::create(Func, Dest, Src0, Src1, Pred, SetFlags));
}
void _push(const VarList &Sources) {
Context.insert(InstARM32Push::create(Func, Sources));
} }
void _push(const VarList &Sources) { Context.insert<InstARM32Push>(Sources); }
void _pop(const VarList &Dests) { void _pop(const VarList &Dests) {
Context.insert(InstARM32Pop::create(Func, Dests)); Context.insert<InstARM32Pop>(Dests);
// Mark dests as modified. // Mark dests as modified.
for (Variable *Dest : Dests) for (Variable *Dest : Dests)
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
} }
void _rbit(Variable *Dest, Variable *Src0, void _rbit(Variable *Dest, Variable *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Rbit::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Rbit>(Dest, Src0, Pred);
} }
void _rev(Variable *Dest, Variable *Src0, void _rev(Variable *Dest, Variable *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Rev::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Rev>(Dest, Src0, Pred);
} }
void _ret(Variable *LR, Variable *Src0 = nullptr) { void _ret(Variable *LR, Variable *Src0 = nullptr) {
Context.insert(InstARM32Ret::create(Func, LR, Src0)); Context.insert<InstARM32Ret>(LR, Src0);
} }
void _rscs(Variable *Dest, Variable *Src0, Operand *Src1, void _rscs(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Rsc>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Rsc::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _rsc(Variable *Dest, Variable *Src0, Operand *Src1, void _rsc(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Rsc::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Rsc>(Dest, Src0, Src1, Pred);
} }
void _rsbs(Variable *Dest, Variable *Src0, Operand *Src1, void _rsbs(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Rsb>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Rsb::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _rsb(Variable *Dest, Variable *Src0, Operand *Src1, void _rsb(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Rsb::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Rsb>(Dest, Src0, Src1, Pred);
} }
void _sbc(Variable *Dest, Variable *Src0, Operand *Src1, void _sbc(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Sbc>(Dest, Src0, Src1, Pred);
} }
void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1, void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Sbc>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _sdiv(Variable *Dest, Variable *Src0, Variable *Src1, void _sdiv(Variable *Dest, Variable *Src0, Variable *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Sdiv::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Sdiv>(Dest, Src0, Src1, Pred);
} }
/// _str, for all your Variable to memory transfers. Addr has the same /// _str, for all your Variable to memory transfers. Addr has the same
/// restrictions that it does in _ldr. /// restrictions that it does in _ldr.
void _str(Variable *Value, OperandARM32Mem *Addr, void _str(Variable *Value, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Str::create(Func, Value, Addr, Pred)); Context.insert<InstARM32Str>(Value, Addr, Pred);
} }
void _strex(Variable *Dest, Variable *Value, OperandARM32Mem *Addr, void _strex(Variable *Dest, Variable *Value, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
// strex requires Dest to be a register other than Value or Addr. This // strex requires Dest to be a register other than Value or Addr. This
// restriction is cleanly represented by adding an "early" definition of // restriction is cleanly represented by adding an "early" definition of
// Dest (or a latter use of all the sources.) // Dest (or a latter use of all the sources.)
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) { if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) {
Context.insert(InstFakeUse::create(Func, Value64->getLo())); Context.insert<InstFakeUse>(Value64->getLo());
Context.insert(InstFakeUse::create(Func, Value64->getHi())); Context.insert<InstFakeUse>(Value64->getHi());
} }
auto *Instr = InstARM32Strex::create(Func, Dest, Value, Addr, Pred); auto *Instr = Context.insert<InstARM32Strex>(Dest, Value, Addr, Pred);
Context.insert(Instr);
Instr->setDestRedefined(); Instr->setDestRedefined();
} }
void _sub(Variable *Dest, Variable *Src0, Operand *Src1, void _sub(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Sub::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Sub>(Dest, Src0, Src1, Pred);
} }
void _subs(Variable *Dest, Variable *Src0, Operand *Src1, void _subs(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
constexpr bool SetFlags = true; constexpr bool SetFlags = true;
Context.insert( Context.insert<InstARM32Sub>(Dest, Src0, Src1, Pred, SetFlags);
InstARM32Sub::create(Func, Dest, Src0, Src1, Pred, SetFlags));
} }
void _sxt(Variable *Dest, Variable *Src0, void _sxt(Variable *Dest, Variable *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Sxt::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Sxt>(Dest, Src0, Pred);
} }
void _tst(Variable *Src0, Operand *Src1, void _tst(Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Tst::create(Func, Src0, Src1, Pred)); Context.insert<InstARM32Tst>(Src0, Src1, Pred);
} }
void _trap() { Context.insert(InstARM32Trap::create(Func)); } void _trap() { Context.insert<InstARM32Trap>(); }
void _udiv(Variable *Dest, Variable *Src0, Variable *Src1, void _udiv(Variable *Dest, Variable *Src0, Variable *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Udiv::create(Func, Dest, Src0, Src1, Pred)); Context.insert<InstARM32Udiv>(Dest, Src0, Src1, Pred);
} }
void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0, void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0,
Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) { Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) {
Context.insert( Context.insert<InstARM32Umull>(DestLo, DestHi, Src0, Src1, Pred);
InstARM32Umull::create(Func, DestLo, DestHi, Src0, Src1, Pred));
// Model the modification to the second dest as a fake def. Note that the // Model the modification to the second dest as a fake def. Note that the
// def is not predicated. // def is not predicated.
Context.insert(InstFakeDef::create(Func, DestHi, DestLo)); Context.insert<InstFakeDef>(DestHi, DestLo);
} }
void _uxt(Variable *Dest, Variable *Src0, void _uxt(Variable *Dest, Variable *Src0,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred)); Context.insert<InstARM32Uxt>(Dest, Src0, Pred);
} }
void _vabs(Variable *Dest, Variable *Src, void _vabs(Variable *Dest, Variable *Src,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vabs::create(Func, Dest, Src, Pred)); Context.insert<InstARM32Vabs>(Dest, Src, Pred);
} }
void _vadd(Variable *Dest, Variable *Src0, Variable *Src1) { void _vadd(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vadd::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vadd>(Dest, Src0, Src1);
} }
void _vcvt(Variable *Dest, Variable *Src, InstARM32Vcvt::VcvtVariant Variant, void _vcvt(Variable *Dest, Variable *Src, InstARM32Vcvt::VcvtVariant Variant,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vcvt::create(Func, Dest, Src, Variant, Pred)); Context.insert<InstARM32Vcvt>(Dest, Src, Variant, Pred);
} }
void _vdiv(Variable *Dest, Variable *Src0, Variable *Src1) { void _vdiv(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vdiv::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vdiv>(Dest, Src0, Src1);
} }
void _vcmp(Variable *Src0, Variable *Src1, void _vcmp(Variable *Src0, Variable *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vcmp::create(Func, Src0, Src1, Pred)); Context.insert<InstARM32Vcmp>(Src0, Src1, Pred);
} }
void _vcmp(Variable *Src0, OperandARM32FlexFpZero *FpZero, void _vcmp(Variable *Src0, OperandARM32FlexFpZero *FpZero,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vcmp::create(Func, Src0, FpZero, Pred)); Context.insert<InstARM32Vcmp>(Src0, FpZero, Pred);
} }
void _veor(Variable *Dest, Variable *Src0, Variable *Src1) { void _veor(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Veor::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Veor>(Dest, Src0, Src1);
} }
void _vmrs(CondARM32::Cond Pred = CondARM32::AL) { void _vmrs(CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vmrs::create(Func, Pred)); Context.insert<InstARM32Vmrs>(Pred);
} }
void _vmla(Variable *Dest, Variable *Src0, Variable *Src1) { void _vmla(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vmla::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vmla>(Dest, Src0, Src1);
} }
void _vmls(Variable *Dest, Variable *Src0, Variable *Src1) { void _vmls(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vmls::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vmls>(Dest, Src0, Src1);
} }
void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) { void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vmul::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vmul>(Dest, Src0, Src1);
} }
void _vsqrt(Variable *Dest, Variable *Src, void _vsqrt(Variable *Dest, Variable *Src,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vsqrt::create(Func, Dest, Src, Pred)); Context.insert<InstARM32Vsqrt>(Dest, Src, Pred);
} }
void _vsub(Variable *Dest, Variable *Src0, Variable *Src1) { void _vsub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vsub::create(Func, Dest, Src0, Src1)); Context.insert<InstARM32Vsub>(Dest, Src0, Src1);
} }
// Iterates over the CFG and determines the maximum outgoing stack arguments // Iterates over the CFG and determines the maximum outgoing stack arguments
......
...@@ -388,7 +388,7 @@ void TargetMIPS32::lowerArguments() { ...@@ -388,7 +388,7 @@ void TargetMIPS32::lowerArguments() {
RegisterArg64On32->getHi()->setRegNum(RegHi); RegisterArg64On32->getHi()->setRegNum(RegHi);
Arg->setIsArg(false); Arg->setIsArg(false);
Args[I] = RegisterArg64On32; Args[I] = RegisterArg64On32;
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); Context.insert<InstAssign>(Arg, RegisterArg);
continue; continue;
} else { } else {
assert(Ty == IceType_i32); assert(Ty == IceType_i32);
...@@ -404,7 +404,7 @@ void TargetMIPS32::lowerArguments() { ...@@ -404,7 +404,7 @@ void TargetMIPS32::lowerArguments() {
RegisterArg->setIsArg(); RegisterArg->setIsArg();
Arg->setIsArg(false); Arg->setIsArg(false);
Args[I] = RegisterArg; Args[I] = RegisterArg;
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); Context.insert<InstAssign>(Arg, RegisterArg);
} }
} }
} }
...@@ -533,13 +533,13 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { ...@@ -533,13 +533,13 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
// TODO(reed kotler): fakedef needed for now until all cases are implemented // TODO(reed kotler): fakedef needed for now until all cases are implemented
auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Context.insert(InstFakeDef::create(Func, DestLo)); Context.insert<InstFakeDef>(DestLo);
Context.insert(InstFakeDef::create(Func, DestHi)); Context.insert<InstFakeDef>(DestHi);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
return; return;
} }
...@@ -602,9 +602,9 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) { ...@@ -602,9 +602,9 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Inst) {
} }
// TODO(reed kotler): // TODO(reed kotler):
// fakedef and fakeuse needed for now until all cases are implemented // fakedef and fakeuse needed for now until all cases are implemented
Context.insert(InstFakeUse::create(Func, Src0R)); Context.insert<InstFakeUse>(Src0R);
Context.insert(InstFakeUse::create(Func, Src1R)); Context.insert<InstFakeUse>(Src1R);
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
UnimplementedError(Func->getContext()->getFlags()); UnimplementedError(Func->getContext()->getFlags());
} }
...@@ -888,7 +888,7 @@ void TargetMIPS32::lowerRet(const InstRet *Inst) { ...@@ -888,7 +888,7 @@ void TargetMIPS32::lowerRet(const InstRet *Inst) {
Variable *R0 = legalizeToReg(loOperand(Src0), RegMIPS32::Reg_V0); Variable *R0 = legalizeToReg(loOperand(Src0), RegMIPS32::Reg_V0);
Variable *R1 = legalizeToReg(hiOperand(Src0), RegMIPS32::Reg_V1); Variable *R1 = legalizeToReg(hiOperand(Src0), RegMIPS32::Reg_V1);
Reg = R0; Reg = R0;
Context.insert(InstFakeUse::create(Func, R1)); Context.insert<InstFakeUse>(R1);
break; break;
} }
...@@ -1022,7 +1022,7 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, ...@@ -1022,7 +1022,7 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
(void)C; (void)C;
// TODO(reed kotler): complete this case for proper implementation // TODO(reed kotler): complete this case for proper implementation
Variable *Reg = makeReg(Ty, RegNum); Variable *Reg = makeReg(Ty, RegNum);
Context.insert(InstFakeDef::create(Func, Reg)); Context.insert<InstFakeDef>(Reg);
return Reg; return Reg;
} else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
uint32_t Value = static_cast<uint32_t>(C32->getValue()); uint32_t Value = static_cast<uint32_t>(C32->getValue());
......
...@@ -116,60 +116,59 @@ public: ...@@ -116,60 +116,59 @@ public:
// minimal syntactic overhead, so that the lowering code can look as close to // minimal syntactic overhead, so that the lowering code can look as close to
// assembly as practical. // assembly as practical.
void _add(Variable *Dest, Variable *Src0, Variable *Src1) { void _add(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32Add::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32Add>(Dest, Src0, Src1);
} }
void _and(Variable *Dest, Variable *Src0, Variable *Src1) { void _and(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32And::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32And>(Dest, Src0, Src1);
} }
void _ret(Variable *RA, Variable *Src0 = nullptr) { void _ret(Variable *RA, Variable *Src0 = nullptr) {
Context.insert(InstMIPS32Ret::create(Func, RA, Src0)); Context.insert<InstMIPS32Ret>(RA, Src0);
} }
void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) { void _addiu(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert(InstMIPS32Addiu::create(Func, Dest, Src, Imm)); Context.insert<InstMIPS32Addiu>(Dest, Src, Imm);
} }
void _lui(Variable *Dest, uint32_t Imm) { void _lui(Variable *Dest, uint32_t Imm) {
Context.insert(InstMIPS32Lui::create(Func, Dest, Imm)); Context.insert<InstMIPS32Lui>(Dest, Imm);
} }
void _mov(Variable *Dest, Operand *Src0) { void _mov(Variable *Dest, Operand *Src0) {
assert(Dest != nullptr); assert(Dest != nullptr);
// Variable* Src0_ = llvm::dyn_cast<Variable>(Src0); // Variable* Src0_ = llvm::dyn_cast<Variable>(Src0);
if (llvm::isa<ConstantRelocatable>(Src0)) { if (llvm::isa<ConstantRelocatable>(Src0)) {
Context.insert(InstMIPS32La::create(Func, Dest, Src0)); Context.insert<InstMIPS32La>(Dest, Src0);
} else { } else {
auto *Instr = InstMIPS32Mov::create(Func, Dest, Src0); auto *Instr = Context.insert<InstMIPS32Mov>(Dest, Src0);
Context.insert(Instr);
if (Instr->isMultiDest()) { if (Instr->isMultiDest()) {
// If Instr is multi-dest, then Dest must be a Variable64On32. We add a // If Instr is multi-dest, then Dest must be a Variable64On32. We add a
// fake-def for Instr.DestHi here. // fake-def for Instr.DestHi here.
assert(llvm::isa<Variable64On32>(Dest)); assert(llvm::isa<Variable64On32>(Dest));
Context.insert(InstFakeDef::create(Func, Instr->getDestHi())); Context.insert<InstFakeDef>(Instr->getDestHi());
} }
} }
} }
void _mul(Variable *Dest, Variable *Src0, Variable *Src1) { void _mul(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32Mul::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32Mul>(Dest, Src0, Src1);
} }
void _or(Variable *Dest, Variable *Src0, Variable *Src1) { void _or(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32Or::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32Or>(Dest, Src0, Src1);
} }
void _ori(Variable *Dest, Variable *Src, uint32_t Imm) { void _ori(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert(InstMIPS32Ori::create(Func, Dest, Src, Imm)); Context.insert<InstMIPS32Ori>(Dest, Src, Imm);
} }
void _sub(Variable *Dest, Variable *Src0, Variable *Src1) { void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32Sub::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
} }
void _xor(Variable *Dest, Variable *Src0, Variable *Src1) { void _xor(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstMIPS32Xor::create(Func, Dest, Src0, Src1)); Context.insert<InstMIPS32Xor>(Dest, Src0, Src1);
} }
void lowerArguments() override; void lowerArguments() override;
......
...@@ -190,7 +190,7 @@ void TargetX8632::lowerCall(const InstCall *Instr) { ...@@ -190,7 +190,7 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
// Generate a FakeUse of register arguments so that they do not get dead // Generate a FakeUse of register arguments so that they do not get dead
// code eliminated as a result of the FakeKill of scratch registers after // code eliminated as a result of the FakeKill of scratch registers after
// the call. // the call.
Context.insert(InstFakeUse::create(Func, Reg)); Context.insert<InstFakeUse>(Reg);
} }
// Generate the call instruction. Assign its result to a temporary with high // Generate the call instruction. Assign its result to a temporary with high
// register allocation weight. // register allocation weight.
...@@ -244,15 +244,14 @@ void TargetX8632::lowerCall(const InstCall *Instr) { ...@@ -244,15 +244,14 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
CallTarget = CallTargetVar; CallTarget = CallTargetVar;
} }
} }
Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget);
Context.insert(NewCall);
if (NeedSandboxing) if (NeedSandboxing)
_bundle_unlock(); _bundle_unlock();
if (ReturnRegHi) if (ReturnRegHi)
Context.insert(InstFakeDef::create(Func, ReturnRegHi)); Context.insert<InstFakeDef>(ReturnRegHi);
// Insert a register-kill pseudo instruction. // Insert a register-kill pseudo instruction.
Context.insert(InstFakeKill::create(Func, NewCall)); Context.insert<InstFakeKill>(NewCall);
if (Dest != nullptr && isScalarFloatingType(Dest->getType())) { if (Dest != nullptr && isScalarFloatingType(Dest->getType())) {
// Special treatment for an FP function which returns its result in st(0). // Special treatment for an FP function which returns its result in st(0).
...@@ -262,13 +261,12 @@ void TargetX8632::lowerCall(const InstCall *Instr) { ...@@ -262,13 +261,12 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
_fstp(Dest); _fstp(Dest);
// Create a fake use of Dest in case it actually isn't used, because st(0) // Create a fake use of Dest in case it actually isn't used, because st(0)
// still needs to be popped. // still needs to be popped.
Context.insert(InstFakeUse::create(Func, Dest)); Context.insert<InstFakeUse>(Dest);
} }
// Generate a FakeUse to keep the call live if necessary. // Generate a FakeUse to keep the call live if necessary.
if (Instr->hasSideEffects() && ReturnReg) { if (Instr->hasSideEffects() && ReturnReg) {
Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); Context.insert<InstFakeUse>(ReturnReg);
Context.insert(FakeUse);
} }
if (!Dest) if (!Dest)
...@@ -324,7 +322,7 @@ void TargetX8632::lowerArguments() { ...@@ -324,7 +322,7 @@ void TargetX8632::lowerArguments() {
Arg->setIsArg(false); Arg->setIsArg(false);
Args[I] = RegisterArg; Args[I] = RegisterArg;
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); Context.insert<InstAssign>(Arg, RegisterArg);
} }
} }
...@@ -339,7 +337,7 @@ void TargetX8632::lowerRet(const InstRet *Inst) { ...@@ -339,7 +337,7 @@ void TargetX8632::lowerRet(const InstRet *Inst) {
Variable *edx = Variable *edx =
legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx); legalizeToReg(hiOperand(Src0), Traits::RegisterSet::Reg_edx);
Reg = eax; Reg = eax;
Context.insert(InstFakeUse::create(Func, edx)); Context.insert<InstFakeUse>(edx);
} else if (isScalarFloatingType(Src0->getType())) { } else if (isScalarFloatingType(Src0->getType())) {
_fld(Src0); _fld(Src0);
} else if (isVectorType(Src0->getType())) { } else if (isVectorType(Src0->getType())) {
...@@ -469,7 +467,7 @@ void TargetX8632::addProlog(CfgNode *Node) { ...@@ -469,7 +467,7 @@ void TargetX8632::addProlog(CfgNode *Node) {
_push(ebp); _push(ebp);
_mov(ebp, esp); _mov(ebp, esp);
// Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
Context.insert(InstFakeUse::create(Func, ebp)); Context.insert<InstFakeUse>(ebp);
} }
// Align the variables area. SpillAreaPaddingBytes is the size of the region // Align the variables area. SpillAreaPaddingBytes is the size of the region
...@@ -633,7 +631,7 @@ void TargetX8632::addEpilog(CfgNode *Node) { ...@@ -633,7 +631,7 @@ void TargetX8632::addEpilog(CfgNode *Node) {
// For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
// use of esp before the assignment of esp=ebp keeps previous esp // use of esp before the assignment of esp=ebp keeps previous esp
// adjustments from being dead-code eliminated. // adjustments from being dead-code eliminated.
Context.insert(InstFakeUse::create(Func, esp)); Context.insert<InstFakeUse>(esp);
_mov(esp, ebp); _mov(esp, ebp);
_pop(ebp); _pop(ebp);
} else { } else {
...@@ -676,7 +674,7 @@ void TargetX8632::addEpilog(CfgNode *Node) { ...@@ -676,7 +674,7 @@ void TargetX8632::addEpilog(CfgNode *Node) {
lowerIndirectJump(T_ecx); lowerIndirectJump(T_ecx);
if (RI->getSrcSize()) { if (RI->getSrcSize()) {
auto *RetValue = llvm::cast<Variable>(RI->getSrc(0)); auto *RetValue = llvm::cast<Variable>(RI->getSrc(0));
Context.insert(InstFakeUse::create(Func, RetValue)); Context.insert<InstFakeUse>(RetValue);
} }
RI->setDeleted(); RI->setDeleted();
} }
......
...@@ -226,12 +226,12 @@ void TargetX8664::lowerCall(const InstCall *Instr) { ...@@ -226,12 +226,12 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
// Generate a FakeUse of register arguments so that they do not get dead // Generate a FakeUse of register arguments so that they do not get dead
// code eliminated as a result of the FakeKill of scratch registers after // code eliminated as a result of the FakeKill of scratch registers after
// the call. // the call.
Context.insert(InstFakeUse::create(Func, Reg)); Context.insert<InstFakeUse>(Reg);
} }
for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) { for (SizeT i = 0, NumGprArgs = GprArgs.size(); i < NumGprArgs; ++i) {
Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i)); Variable *Reg = legalizeToReg(GprArgs[i], getRegisterForGprArgNum(i));
Context.insert(InstFakeUse::create(Func, Reg)); Context.insert<InstFakeUse>(Reg);
} }
// Generate the call instruction. Assign its result to a temporary with high // Generate the call instruction. Assign its result to a temporary with high
...@@ -271,8 +271,7 @@ void TargetX8664::lowerCall(const InstCall *Instr) { ...@@ -271,8 +271,7 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
if (NeedSandboxing) { if (NeedSandboxing) {
llvm_unreachable("X86-64 Sandboxing codegen not implemented."); llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
} }
Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget); auto *NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget);
Context.insert(NewCall);
if (NeedSandboxing) { if (NeedSandboxing) {
llvm_unreachable("X86-64 Sandboxing codegen not implemented."); llvm_unreachable("X86-64 Sandboxing codegen not implemented.");
} }
...@@ -286,12 +285,11 @@ void TargetX8664::lowerCall(const InstCall *Instr) { ...@@ -286,12 +285,11 @@ void TargetX8664::lowerCall(const InstCall *Instr) {
} }
// Insert a register-kill pseudo instruction. // Insert a register-kill pseudo instruction.
Context.insert(InstFakeKill::create(Func, NewCall)); Context.insert<InstFakeKill>(NewCall);
// Generate a FakeUse to keep the call live if necessary. // Generate a FakeUse to keep the call live if necessary.
if (Instr->hasSideEffects() && ReturnReg) { if (Instr->hasSideEffects() && ReturnReg) {
Inst *FakeUse = InstFakeUse::create(Func, ReturnReg); Context.insert<InstFakeUse>(ReturnReg);
Context.insert(FakeUse);
} }
if (!Dest) if (!Dest)
...@@ -356,7 +354,7 @@ void TargetX8664::lowerArguments() { ...@@ -356,7 +354,7 @@ void TargetX8664::lowerArguments() {
Arg->setIsArg(false); Arg->setIsArg(false);
Args[i] = RegisterArg; Args[i] = RegisterArg;
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); Context.insert<InstAssign>(Arg, RegisterArg);
} }
} }
...@@ -486,7 +484,7 @@ void TargetX8664::addProlog(CfgNode *Node) { ...@@ -486,7 +484,7 @@ void TargetX8664::addProlog(CfgNode *Node) {
_push(ebp); _push(ebp);
_mov(ebp, esp); _mov(ebp, esp);
// Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode). // Keep ebp live for late-stage liveness analysis (e.g. asm-verbose mode).
Context.insert(InstFakeUse::create(Func, ebp)); Context.insert<InstFakeUse>(ebp);
} }
// Align the variables area. SpillAreaPaddingBytes is the size of the region // Align the variables area. SpillAreaPaddingBytes is the size of the region
...@@ -645,7 +643,7 @@ void TargetX8664::addEpilog(CfgNode *Node) { ...@@ -645,7 +643,7 @@ void TargetX8664::addEpilog(CfgNode *Node) {
// For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake
// use of esp before the assignment of esp=ebp keeps previous esp // use of esp before the assignment of esp=ebp keeps previous esp
// adjustments from being dead-code eliminated. // adjustments from being dead-code eliminated.
Context.insert(InstFakeUse::create(Func, esp)); Context.insert<InstFakeUse>(esp);
_mov(esp, ebp); _mov(esp, ebp);
_pop(ebp); _pop(ebp);
} else { } else {
......
...@@ -250,7 +250,7 @@ protected: ...@@ -250,7 +250,7 @@ protected:
/// function. Otherwise some esp adjustments get dead-code eliminated. /// function. Otherwise some esp adjustments get dead-code eliminated.
void keepEspLiveAtExit() { void keepEspLiveAtExit() {
Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg()); Variable *esp = Func->getTarget()->getPhysicalRegister(getStackReg());
Context.insert(InstFakeUse::create(Func, esp)); Context.insert<InstFakeUse>(esp);
} }
/// Operand legalization helpers. To deal with address mode constraints, the /// Operand legalization helpers. To deal with address mode constraints, the
...@@ -327,117 +327,115 @@ protected: ...@@ -327,117 +327,115 @@ protected:
/// minimal syntactic overhead, so that the lowering code can look as close to /// minimal syntactic overhead, so that the lowering code can look as close to
/// assembly as practical. /// assembly as practical.
void _adc(Variable *Dest, Operand *Src0) { void _adc(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Adc::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Adc>(Dest, Src0);
} }
void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _adc_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::AdcRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::AdcRMW>(DestSrc0, Src1);
} }
void _add(Variable *Dest, Operand *Src0) { void _add(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Add::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Add>(Dest, Src0);
} }
void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _add_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::AddRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::AddRMW>(DestSrc0, Src1);
} }
void _addps(Variable *Dest, Operand *Src0) { void _addps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Addps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Addps>(Dest, Src0);
} }
void _addss(Variable *Dest, Operand *Src0) { void _addss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Addss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Addss>(Dest, Src0);
} }
void _and(Variable *Dest, Operand *Src0) { void _and(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::And::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::And>(Dest, Src0);
} }
void _andnps(Variable *Dest, Operand *Src0) { void _andnps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Andnps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Andnps>(Dest, Src0);
} }
void _andps(Variable *Dest, Operand *Src0) { void _andps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Andps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Andps>(Dest, Src0);
} }
void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _and_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::AndRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::AndRMW>(DestSrc0, Src1);
} }
void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Blendvps::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Blendvps>(Dest, Src0, Src1);
} }
void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue, void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue,
CfgNode *TargetFalse) { CfgNode *TargetFalse) {
Context.insert(Traits::Insts::Br::create( Context.insert<typename Traits::Insts::Br>(
Func, TargetTrue, TargetFalse, Condition, Traits::Insts::Br::Far)); TargetTrue, TargetFalse, Condition, Traits::Insts::Br::Far);
} }
void _br(CfgNode *Target) { void _br(CfgNode *Target) {
Context.insert( Context.insert<typename Traits::Insts::Br>(Target, Traits::Insts::Br::Far);
Traits::Insts::Br::create(Func, Target, Traits::Insts::Br::Far));
} }
void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) { void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) {
Context.insert(Traits::Insts::Br::create(Func, Target, Condition, Context.insert<typename Traits::Insts::Br>(Target, Condition,
Traits::Insts::Br::Far)); Traits::Insts::Br::Far);
} }
void _br(typename Traits::Cond::BrCond Condition, void _br(typename Traits::Cond::BrCond Condition,
typename Traits::Insts::Label *Label, typename Traits::Insts::Label *Label,
typename Traits::Insts::Br::Mode Kind = Traits::Insts::Br::Near) { typename Traits::Insts::Br::Mode Kind = Traits::Insts::Br::Near) {
Context.insert(Traits::Insts::Br::create(Func, Label, Condition, Kind)); Context.insert<typename Traits::Insts::Br>(Label, Condition, Kind);
} }
void _bsf(Variable *Dest, Operand *Src0) { void _bsf(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Bsf::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Bsf>(Dest, Src0);
} }
void _bsr(Variable *Dest, Operand *Src0) { void _bsr(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Bsr::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Bsr>(Dest, Src0);
} }
void _bswap(Variable *SrcDest) { void _bswap(Variable *SrcDest) {
Context.insert(Traits::Insts::Bswap::create(Func, SrcDest)); Context.insert<typename Traits::Insts::Bswap>(SrcDest);
} }
void _cbwdq(Variable *Dest, Operand *Src0) { void _cbwdq(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Cbwdq::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Cbwdq>(Dest, Src0);
} }
void _cmov(Variable *Dest, Operand *Src0, void _cmov(Variable *Dest, Operand *Src0,
typename Traits::Cond::BrCond Condition) { typename Traits::Cond::BrCond Condition) {
Context.insert(Traits::Insts::Cmov::create(Func, Dest, Src0, Condition)); Context.insert<typename Traits::Insts::Cmov>(Dest, Src0, Condition);
} }
void _cmp(Operand *Src0, Operand *Src1) { void _cmp(Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Icmp::create(Func, Src0, Src1)); Context.insert<typename Traits::Insts::Icmp>(Src0, Src1);
} }
void _cmpps(Variable *Dest, Operand *Src0, void _cmpps(Variable *Dest, Operand *Src0,
typename Traits::Cond::CmppsCond Condition) { typename Traits::Cond::CmppsCond Condition) {
Context.insert(Traits::Insts::Cmpps::create(Func, Dest, Src0, Condition)); Context.insert<typename Traits::Insts::Cmpps>(Dest, Src0, Condition);
} }
void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
bool Locked) { bool Locked) {
Context.insert( Context.insert<typename Traits::Insts::Cmpxchg>(DestOrAddr, Eax, Desired,
Traits::Insts::Cmpxchg::create(Func, DestOrAddr, Eax, Desired, Locked)); Locked);
// Mark eax as possibly modified by cmpxchg. // Mark eax as possibly modified by cmpxchg.
Context.insert( Context.insert<InstFakeDef>(Eax, llvm::dyn_cast<Variable>(DestOrAddr));
InstFakeDef::create(Func, Eax, llvm::dyn_cast<Variable>(DestOrAddr)));
_set_dest_redefined(); _set_dest_redefined();
Context.insert(InstFakeUse::create(Func, Eax)); Context.insert<InstFakeUse>(Eax);
} }
void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx, void _cmpxchg8b(typename Traits::X86OperandMem *Addr, Variable *Edx,
Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) { Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked) {
Context.insert(Traits::Insts::Cmpxchg8b::create(Func, Addr, Edx, Eax, Ecx, Context.insert<typename Traits::Insts::Cmpxchg8b>(Addr, Edx, Eax, Ecx, Ebx,
Ebx, Locked)); Locked);
// Mark edx, and eax as possibly modified by cmpxchg8b. // Mark edx, and eax as possibly modified by cmpxchg8b.
Context.insert(InstFakeDef::create(Func, Edx)); Context.insert<InstFakeDef>(Edx);
_set_dest_redefined(); _set_dest_redefined();
Context.insert(InstFakeUse::create(Func, Edx)); Context.insert<InstFakeUse>(Edx);
Context.insert(InstFakeDef::create(Func, Eax)); Context.insert<InstFakeDef>(Eax);
_set_dest_redefined(); _set_dest_redefined();
Context.insert(InstFakeUse::create(Func, Eax)); Context.insert<InstFakeUse>(Eax);
} }
void _cvt(Variable *Dest, Operand *Src0, void _cvt(Variable *Dest, Operand *Src0,
typename Traits::Insts::Cvt::CvtVariant Variant) { typename Traits::Insts::Cvt::CvtVariant Variant) {
Context.insert(Traits::Insts::Cvt::create(Func, Dest, Src0, Variant)); Context.insert<typename Traits::Insts::Cvt>(Dest, Src0, Variant);
} }
void _div(Variable *Dest, Operand *Src0, Operand *Src1) { void _div(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Div::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Div>(Dest, Src0, Src1);
} }
void _divps(Variable *Dest, Operand *Src0) { void _divps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Divps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Divps>(Dest, Src0);
} }
void _divss(Variable *Dest, Operand *Src0) { void _divss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Divss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Divss>(Dest, Src0);
} }
template <typename T = Traits> template <typename T = Traits>
typename std::enable_if<T::UsesX87, void>::type _fld(Operand *Src0) { typename std::enable_if<T::UsesX87, void>::type _fld(Operand *Src0) {
Context.insert(Traits::Insts::template Fld<>::create(Func, Src0)); Context.insert<typename Traits::Insts::template Fld<>>(Src0);
} }
// TODO(jpp): when implementing the X8664 calling convention, make sure x8664 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664
// does not invoke this method, and remove it. // does not invoke this method, and remove it.
...@@ -447,7 +445,7 @@ protected: ...@@ -447,7 +445,7 @@ protected:
} }
template <typename T = Traits> template <typename T = Traits>
typename std::enable_if<T::UsesX87, void>::type _fstp(Variable *Dest) { typename std::enable_if<T::UsesX87, void>::type _fstp(Variable *Dest) {
Context.insert(Traits::Insts::template Fstp<>::create(Func, Dest)); Context.insert<typename Traits::Insts::template Fstp<>>(Dest);
} }
// TODO(jpp): when implementing the X8664 calling convention, make sure x8664 // TODO(jpp): when implementing the X8664 calling convention, make sure x8664
// does not invoke this method, and remove it. // does not invoke this method, and remove it.
...@@ -456,24 +454,24 @@ protected: ...@@ -456,24 +454,24 @@ protected:
llvm::report_fatal_error("fstp is not available in x86-64"); llvm::report_fatal_error("fstp is not available in x86-64");
} }
void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) { void _idiv(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Idiv::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Idiv>(Dest, Src0, Src1);
} }
void _imul(Variable *Dest, Operand *Src0) { void _imul(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Imul::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Imul>(Dest, Src0);
} }
void _imul_imm(Variable *Dest, Operand *Src0, Constant *Imm) { void _imul_imm(Variable *Dest, Operand *Src0, Constant *Imm) {
Context.insert(Traits::Insts::ImulImm::create(Func, Dest, Src0, Imm)); Context.insert<typename Traits::Insts::ImulImm>(Dest, Src0, Imm);
} }
void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) { void _insertps(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Insertps::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Insertps>(Dest, Src0, Src1);
} }
void _jmp(Operand *Target) { void _jmp(Operand *Target) {
Context.insert(Traits::Insts::Jmp::create(Func, Target)); Context.insert<typename Traits::Insts::Jmp>(Target);
} }
void _lea(Variable *Dest, Operand *Src0) { void _lea(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Lea::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Lea>(Dest, Src0);
} }
void _mfence() { Context.insert(Traits::Insts::Mfence::create(Func)); } void _mfence() { Context.insert<typename Traits::Insts::Mfence>(); }
/// Moves can be used to redefine registers, creating "partial kills" for /// Moves can be used to redefine registers, creating "partial kills" for
/// liveness. Mark where moves are used in this way. /// liveness. Mark where moves are used in this way.
void _redefined(Inst *MovInst, bool IsRedefinition = true) { void _redefined(Inst *MovInst, bool IsRedefinition = true) {
...@@ -483,220 +481,214 @@ protected: ...@@ -483,220 +481,214 @@ protected:
/// If Dest=nullptr is passed in, then a new variable is created, marked as /// If Dest=nullptr is passed in, then a new variable is created, marked as
/// infinite register allocation weight, and returned through the in/out Dest /// infinite register allocation weight, and returned through the in/out Dest
/// argument. /// argument.
Inst *_mov(Variable *&Dest, Operand *Src0, typename Traits::Insts::Mov *_mov(Variable *&Dest, Operand *Src0,
int32_t RegNum = Variable::NoRegister) { int32_t RegNum = Variable::NoRegister) {
if (Dest == nullptr) if (Dest == nullptr)
Dest = makeReg(Src0->getType(), RegNum); Dest = makeReg(Src0->getType(), RegNum);
Inst *NewInst = Traits::Insts::Mov::create(Func, Dest, Src0); return Context.insert<typename Traits::Insts::Mov>(Dest, Src0);
Context.insert(NewInst);
return NewInst;
} }
Inst *_movp(Variable *Dest, Operand *Src0) { typename Traits::Insts::Movp *_movp(Variable *Dest, Operand *Src0) {
Inst *NewInst = Traits::Insts::Movp::create(Func, Dest, Src0); return Context.insert<typename Traits::Insts::Movp>(Dest, Src0);
Context.insert(NewInst);
return NewInst;
} }
void _movd(Variable *Dest, Operand *Src0) { void _movd(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Movd::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Movd>(Dest, Src0);
} }
void _movq(Variable *Dest, Operand *Src0) { void _movq(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Movq::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Movq>(Dest, Src0);
} }
void _movss(Variable *Dest, Variable *Src0) { void _movss(Variable *Dest, Variable *Src0) {
Context.insert(Traits::Insts::MovssRegs::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::MovssRegs>(Dest, Src0);
} }
void _movsx(Variable *Dest, Operand *Src0) { void _movsx(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Movsx::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Movsx>(Dest, Src0);
} }
void _movzx(Variable *Dest, Operand *Src0) { void _movzx(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Movzx::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Movzx>(Dest, Src0);
} }
void _maxss(Variable *Dest, Operand *Src0) { void _maxss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Maxss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Maxss>(Dest, Src0);
} }
void _minss(Variable *Dest, Operand *Src0) { void _minss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Minss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Minss>(Dest, Src0);
} }
void _mul(Variable *Dest, Variable *Src0, Operand *Src1) { void _mul(Variable *Dest, Variable *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Mul::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Mul>(Dest, Src0, Src1);
} }
void _mulps(Variable *Dest, Operand *Src0) { void _mulps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Mulps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Mulps>(Dest, Src0);
} }
void _mulss(Variable *Dest, Operand *Src0) { void _mulss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Mulss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Mulss>(Dest, Src0);
} }
void _neg(Variable *SrcDest) { void _neg(Variable *SrcDest) {
Context.insert(Traits::Insts::Neg::create(Func, SrcDest)); Context.insert<typename Traits::Insts::Neg>(SrcDest);
} }
void _nop(SizeT Variant) { void _nop(SizeT Variant) {
Context.insert(Traits::Insts::Nop::create(Func, Variant)); Context.insert<typename Traits::Insts::Nop>(Variant);
} }
void _or(Variable *Dest, Operand *Src0) { void _or(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Or::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Or>(Dest, Src0);
} }
void _orps(Variable *Dest, Operand *Src0) { void _orps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Orps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Orps>(Dest, Src0);
} }
void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _or_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::OrRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::OrRMW>(DestSrc0, Src1);
} }
void _padd(Variable *Dest, Operand *Src0) { void _padd(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Padd::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Padd>(Dest, Src0);
} }
void _pand(Variable *Dest, Operand *Src0) { void _pand(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pand::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pand>(Dest, Src0);
} }
void _pandn(Variable *Dest, Operand *Src0) { void _pandn(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pandn::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pandn>(Dest, Src0);
} }
void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) { void _pblendvb(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Pblendvb::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Pblendvb>(Dest, Src0, Src1);
} }
void _pcmpeq(Variable *Dest, Operand *Src0) { void _pcmpeq(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pcmpeq::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pcmpeq>(Dest, Src0);
} }
void _pcmpgt(Variable *Dest, Operand *Src0) { void _pcmpgt(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pcmpgt::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pcmpgt>(Dest, Src0);
} }
void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) { void _pextr(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Pextr::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Pextr>(Dest, Src0, Src1);
} }
void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) { void _pinsr(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Pinsr::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Pinsr>(Dest, Src0, Src1);
} }
void _pmull(Variable *Dest, Operand *Src0) { void _pmull(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pmull::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pmull>(Dest, Src0);
} }
void _pmuludq(Variable *Dest, Operand *Src0) { void _pmuludq(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pmuludq::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pmuludq>(Dest, Src0);
} }
void _pop(Variable *Dest) { void _pop(Variable *Dest) {
Context.insert(Traits::Insts::Pop::create(Func, Dest)); Context.insert<typename Traits::Insts::Pop>(Dest);
} }
void _por(Variable *Dest, Operand *Src0) { void _por(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Por::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Por>(Dest, Src0);
} }
void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) { void _pshufd(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Pshufd::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Pshufd>(Dest, Src0, Src1);
} }
void _psll(Variable *Dest, Operand *Src0) { void _psll(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Psll::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Psll>(Dest, Src0);
} }
void _psra(Variable *Dest, Operand *Src0) { void _psra(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Psra::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Psra>(Dest, Src0);
} }
void _psrl(Variable *Dest, Operand *Src0) { void _psrl(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Psrl::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Psrl>(Dest, Src0);
} }
void _psub(Variable *Dest, Operand *Src0) { void _psub(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Psub::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Psub>(Dest, Src0);
} }
void _push(Variable *Src0) { void _push(Variable *Src0) {
Context.insert(Traits::Insts::Push::create(Func, Src0)); Context.insert<typename Traits::Insts::Push>(Src0);
} }
void _pxor(Variable *Dest, Operand *Src0) { void _pxor(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Pxor::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Pxor>(Dest, Src0);
} }
void _ret(Variable *Src0 = nullptr) { void _ret(Variable *Src0 = nullptr) {
Context.insert(Traits::Insts::Ret::create(Func, Src0)); Context.insert<typename Traits::Insts::Ret>(Src0);
} }
void _rol(Variable *Dest, Operand *Src0) { void _rol(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Rol::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Rol>(Dest, Src0);
} }
void _sar(Variable *Dest, Operand *Src0) { void _sar(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Sar::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Sar>(Dest, Src0);
} }
void _sbb(Variable *Dest, Operand *Src0) { void _sbb(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Sbb::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Sbb>(Dest, Src0);
} }
void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _sbb_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::SbbRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::SbbRMW>(DestSrc0, Src1);
} }
void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) { void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) {
Context.insert(Traits::Insts::Setcc::create(Func, Dest, Condition)); Context.insert<typename Traits::Insts::Setcc>(Dest, Condition);
} }
void _shl(Variable *Dest, Operand *Src0) { void _shl(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Shl::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Shl>(Dest, Src0);
} }
void _shld(Variable *Dest, Variable *Src0, Operand *Src1) { void _shld(Variable *Dest, Variable *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Shld::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Shld>(Dest, Src0, Src1);
} }
void _shr(Variable *Dest, Operand *Src0) { void _shr(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Shr::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Shr>(Dest, Src0);
} }
void _shrd(Variable *Dest, Variable *Src0, Operand *Src1) { void _shrd(Variable *Dest, Variable *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Shrd::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Shrd>(Dest, Src0, Src1);
} }
void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) { void _shufps(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Shufps::create(Func, Dest, Src0, Src1)); Context.insert<typename Traits::Insts::Shufps>(Dest, Src0, Src1);
} }
void _sqrtss(Variable *Dest, Operand *Src0) { void _sqrtss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Sqrtss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Sqrtss>(Dest, Src0);
} }
void _store(Operand *Value, typename Traits::X86Operand *Mem) { void _store(Operand *Value, typename Traits::X86Operand *Mem) {
Context.insert(Traits::Insts::Store::create(Func, Value, Mem)); Context.insert<typename Traits::Insts::Store>(Value, Mem);
} }
void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) { void _storep(Variable *Value, typename Traits::X86OperandMem *Mem) {
Context.insert(Traits::Insts::StoreP::create(Func, Value, Mem)); Context.insert<typename Traits::Insts::StoreP>(Value, Mem);
} }
void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) { void _storeq(Variable *Value, typename Traits::X86OperandMem *Mem) {
Context.insert(Traits::Insts::StoreQ::create(Func, Value, Mem)); Context.insert<typename Traits::Insts::StoreQ>(Value, Mem);
} }
void _sub(Variable *Dest, Operand *Src0) { void _sub(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Sub::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Sub>(Dest, Src0);
} }
void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _sub_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::SubRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::SubRMW>(DestSrc0, Src1);
} }
void _subps(Variable *Dest, Operand *Src0) { void _subps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Subps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Subps>(Dest, Src0);
} }
void _subss(Variable *Dest, Operand *Src0) { void _subss(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Subss::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Subss>(Dest, Src0);
} }
void _test(Operand *Src0, Operand *Src1) { void _test(Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Test::create(Func, Src0, Src1)); Context.insert<typename Traits::Insts::Test>(Src0, Src1);
} }
void _ucomiss(Operand *Src0, Operand *Src1) { void _ucomiss(Operand *Src0, Operand *Src1) {
Context.insert(Traits::Insts::Ucomiss::create(Func, Src0, Src1)); Context.insert<typename Traits::Insts::Ucomiss>(Src0, Src1);
} }
void _ud2() { Context.insert(Traits::Insts::UD2::create(Func)); } void _ud2() { Context.insert<typename Traits::Insts::UD2>(); }
void _xadd(Operand *Dest, Variable *Src, bool Locked) { void _xadd(Operand *Dest, Variable *Src, bool Locked) {
Context.insert(Traits::Insts::Xadd::create(Func, Dest, Src, Locked)); Context.insert<typename Traits::Insts::Xadd>(Dest, Src, Locked);
// The xadd exchanges Dest and Src (modifying Src). Model that update with // The xadd exchanges Dest and Src (modifying Src). Model that update with
// a FakeDef followed by a FakeUse. // a FakeDef followed by a FakeUse.
Context.insert( Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest));
InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
_set_dest_redefined(); _set_dest_redefined();
Context.insert(InstFakeUse::create(Func, Src)); Context.insert<InstFakeUse>(Src);
} }
void _xchg(Operand *Dest, Variable *Src) { void _xchg(Operand *Dest, Variable *Src) {
Context.insert(Traits::Insts::Xchg::create(Func, Dest, Src)); Context.insert<typename Traits::Insts::Xchg>(Dest, Src);
// The xchg modifies Dest and Src -- model that update with a // The xchg modifies Dest and Src -- model that update with a
// FakeDef/FakeUse. // FakeDef/FakeUse.
Context.insert( Context.insert<InstFakeDef>(Src, llvm::dyn_cast<Variable>(Dest));
InstFakeDef::create(Func, Src, llvm::dyn_cast<Variable>(Dest)));
_set_dest_redefined(); _set_dest_redefined();
Context.insert(InstFakeUse::create(Func, Src)); Context.insert<InstFakeUse>(Src);
} }
void _xor(Variable *Dest, Operand *Src0) { void _xor(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Xor::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Xor>(Dest, Src0);
} }
void _xorps(Variable *Dest, Operand *Src0) { void _xorps(Variable *Dest, Operand *Src0) {
Context.insert(Traits::Insts::Xorps::create(Func, Dest, Src0)); Context.insert<typename Traits::Insts::Xorps>(Dest, Src0);
} }
void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) { void _xor_rmw(typename Traits::X86OperandMem *DestSrc0, Operand *Src1) {
Context.insert(Traits::Insts::XorRMW::create(Func, DestSrc0, Src1)); Context.insert<typename Traits::Insts::XorRMW>(DestSrc0, Src1);
} }
void _iaca_start() { void _iaca_start() {
if (!BuildDefs::minimal()) if (!BuildDefs::minimal())
Context.insert(Traits::Insts::IacaStart::create(Func)); Context.insert<typename Traits::Insts::IacaStart>();
} }
void _iaca_end() { void _iaca_end() {
if (!BuildDefs::minimal()) if (!BuildDefs::minimal())
Context.insert(Traits::Insts::IacaEnd::create(Func)); Context.insert<typename Traits::Insts::IacaEnd>();
} }
/// This class helps wrap IACA markers around the code generated by the /// This class helps wrap IACA markers around the code generated by the
......
...@@ -1016,7 +1016,7 @@ void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) { ...@@ -1016,7 +1016,7 @@ void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
// value to Dest, as Dest is rematerializable. // value to Dest, as Dest is rematerializable.
assert(Dest->isRematerializable()); assert(Dest->isRematerializable());
FixedAllocaSizeBytes += Value; FixedAllocaSizeBytes += Value;
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
} else { } else {
_sub(esp, Ctx->getConstantInt32(Value)); _sub(esp, Ctx->getConstantInt32(Value));
} }
...@@ -1358,7 +1358,7 @@ template <class Machine> ...@@ -1358,7 +1358,7 @@ template <class Machine>
void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
Variable *Dest = Inst->getDest(); Variable *Dest = Inst->getDest();
if (Dest->isRematerializable()) { if (Dest->isRematerializable()) {
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
return; return;
} }
Type Ty = Dest->getType(); Type Ty = Dest->getType();
...@@ -1476,7 +1476,7 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) { ...@@ -1476,7 +1476,7 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
_mul(T_4Lo, T_3, Src1Lo); _mul(T_4Lo, T_3, Src1Lo);
// The mul instruction produces two dest variables, edx:eax. We create a // The mul instruction produces two dest variables, edx:eax. We create a
// fake definition of edx to account for this. // fake definition of edx to account for this.
Context.insert(InstFakeDef::create(Func, T_4Hi, T_4Lo)); Context.insert<InstFakeDef>(T_4Hi, T_4Lo);
_mov(DestLo, T_4Lo); _mov(DestLo, T_4Lo);
_add(T_4Hi, T_1); _add(T_4Hi, T_1);
_add(T_4Hi, T_2); _add(T_4Hi, T_2);
...@@ -1911,7 +1911,7 @@ template <class Machine> ...@@ -1911,7 +1911,7 @@ template <class Machine>
void TargetX86Base<Machine>::lowerAssign(const InstAssign *Inst) { void TargetX86Base<Machine>::lowerAssign(const InstAssign *Inst) {
Variable *Dest = Inst->getDest(); Variable *Dest = Inst->getDest();
if (Dest->isRematerializable()) { if (Dest->isRematerializable()) {
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
return; return;
} }
Operand *Src = Inst->getSrc(0); Operand *Src = Inst->getSrc(0);
...@@ -2377,7 +2377,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) { ...@@ -2377,7 +2377,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// Technically, the Spill is defined after the _store happens, but // Technically, the Spill is defined after the _store happens, but
// SpillLo is considered a "use" of Spill so define Spill before it is // SpillLo is considered a "use" of Spill so define Spill before it is
// used. // used.
Context.insert(InstFakeDef::create(Func, Spill)); Context.insert<InstFakeDef>(Spill);
_store(T_Lo, SpillLo); _store(T_Lo, SpillLo);
_mov(T_Hi, hiOperand(Src0)); _mov(T_Hi, hiOperand(Src0));
_store(T_Hi, SpillHi); _store(T_Hi, SpillHi);
...@@ -2450,7 +2450,7 @@ void TargetX86Base<Machine>::lowerExtractElement( ...@@ -2450,7 +2450,7 @@ void TargetX86Base<Machine>::lowerExtractElement(
// used here. // used here.
// _movss is a binary instruction, so the FakeDef is needed to keep the // _movss is a binary instruction, so the FakeDef is needed to keep the
// live range analysis consistent. // live range analysis consistent.
Context.insert(InstFakeDef::create(Func, ExtractedElementR)); Context.insert<InstFakeDef>(ExtractedElementR);
_movss(ExtractedElementR, T); _movss(ExtractedElementR, T);
} }
} else { } else {
...@@ -2886,7 +2886,7 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp, ...@@ -2886,7 +2886,7 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
// sometimes avoid a move before the OR. // sometimes avoid a move before the OR.
_mov(Temp, Src0HiRM); _mov(Temp, Src0HiRM);
_or(Temp, Src0LoRM); _or(Temp, Src0LoRM);
Context.insert(InstFakeUse::create(Func, Temp)); Context.insert<InstFakeUse>(Temp);
setccOrConsumer(Traits::Cond::Br_e, Dest, Consumer); setccOrConsumer(Traits::Cond::Br_e, Dest, Consumer);
return; return;
case InstIcmp::Ne: case InstIcmp::Ne:
...@@ -2895,7 +2895,7 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp, ...@@ -2895,7 +2895,7 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
// sometimes avoid a move before the OR. // sometimes avoid a move before the OR.
_mov(Temp, Src0HiRM); _mov(Temp, Src0HiRM);
_or(Temp, Src0LoRM); _or(Temp, Src0LoRM);
Context.insert(InstFakeUse::create(Func, Temp)); Context.insert<InstFakeUse>(Temp);
setccOrConsumer(Traits::Cond::Br_ne, Dest, Consumer); setccOrConsumer(Traits::Cond::Br_ne, Dest, Consumer);
return; return;
case InstIcmp::Uge: case InstIcmp::Uge:
...@@ -3060,8 +3060,8 @@ void TargetX86Base<Machine>::lowerArithAndConsumer(const InstArithmetic *Arith, ...@@ -3060,8 +3060,8 @@ void TargetX86Base<Machine>::lowerArithAndConsumer(const InstArithmetic *Arith,
llvm::report_fatal_error("Expected a consumer instruction"); llvm::report_fatal_error("Expected a consumer instruction");
} }
if (const auto *Br = llvm::dyn_cast<InstBr>(Consumer)) { if (const auto *Br = llvm::dyn_cast<InstBr>(Consumer)) {
Context.insert(InstFakeUse::create(Func, T)); Context.insert<InstFakeUse>(T);
Context.insert(InstFakeDef::create(Func, Dest)); Context.insert<InstFakeDef>(Dest);
_br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse()); _br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse());
return; return;
} }
...@@ -3290,8 +3290,8 @@ void TargetX86Base<Machine>::lowerIntrinsicCall( ...@@ -3290,8 +3290,8 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
auto *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T); auto *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
lowerCast(Cast); lowerCast(Cast);
// Make sure that the atomic load isn't elided when unused. // Make sure that the atomic load isn't elided when unused.
Context.insert(InstFakeUse::create(Func, Dest64On32->getLo())); Context.insert<InstFakeUse>(Dest64On32->getLo());
Context.insert(InstFakeUse::create(Func, Dest64On32->getHi())); Context.insert<InstFakeUse>(Dest64On32->getHi());
return; return;
} }
} }
...@@ -3300,8 +3300,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall( ...@@ -3300,8 +3300,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
// Make sure the atomic load isn't elided when unused, by adding a FakeUse. // Make sure the atomic load isn't elided when unused, by adding a FakeUse.
// Since lowerLoad may fuse the load w/ an arithmetic instruction, insert // Since lowerLoad may fuse the load w/ an arithmetic instruction, insert
// the FakeUse on the last-inserted instruction's dest. // the FakeUse on the last-inserted instruction's dest.
Context.insert( Context.insert<InstFakeUse>(Context.getLastInserted()->getDest());
InstFakeUse::create(Func, Context.getLastInserted()->getDest()));
return; return;
} }
case Intrinsics::AtomicRMW: case Intrinsics::AtomicRMW:
...@@ -3840,17 +3839,17 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo, ...@@ -3840,17 +3839,17 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
if (auto *ValVar = llvm::dyn_cast<Variable>(Val)) { if (auto *ValVar = llvm::dyn_cast<Variable>(Val)) {
auto *ValLo = llvm::cast<Variable>(loOperand(ValVar)); auto *ValLo = llvm::cast<Variable>(loOperand(ValVar));
auto *ValHi = llvm::cast<Variable>(hiOperand(ValVar)); auto *ValHi = llvm::cast<Variable>(hiOperand(ValVar));
Context.insert(InstFakeUse::create(Func, ValLo)); Context.insert<InstFakeUse>(ValLo);
Context.insert(InstFakeUse::create(Func, ValHi)); Context.insert<InstFakeUse>(ValHi);
} }
} else { } else {
// For xchg, the loop is slightly smaller and ebx/ecx are used. // For xchg, the loop is slightly smaller and ebx/ecx are used.
Context.insert(InstFakeUse::create(Func, T_ebx)); Context.insert<InstFakeUse>(T_ebx);
Context.insert(InstFakeUse::create(Func, T_ecx)); Context.insert<InstFakeUse>(T_ecx);
} }
// The address base (if any) is also reused in the loop. // The address base (if any) is also reused in the loop.
if (Variable *Base = Addr->getBase()) if (Variable *Base = Addr->getBase())
Context.insert(InstFakeUse::create(Func, Base)); Context.insert<InstFakeUse>(Base);
auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
_mov(DestLo, T_eax); _mov(DestLo, T_eax);
...@@ -3875,9 +3874,7 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo, ...@@ -3875,9 +3874,7 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
} }
Variable *T_eax = makeReg(Ty, Eax); Variable *T_eax = makeReg(Ty, Eax);
_mov(T_eax, Addr); _mov(T_eax, Addr);
typename Traits::Insts::Label *Label = auto *Label = Context.insert<typename Traits::Insts::Label>(this);
Traits::Insts::Label::create(Func, this);
Context.insert(Label);
// We want to pick a different register for T than Eax, so don't use // We want to pick a different register for T than Eax, so don't use
// _mov(T == nullptr, T_eax). // _mov(T == nullptr, T_eax).
Variable *T = makeReg(Ty); Variable *T = makeReg(Ty);
...@@ -3889,11 +3886,11 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo, ...@@ -3889,11 +3886,11 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
// If Val is a variable, model the extended live range of Val through // If Val is a variable, model the extended live range of Val through
// the end of the loop, since it will be re-used by the loop. // the end of the loop, since it will be re-used by the loop.
if (auto *ValVar = llvm::dyn_cast<Variable>(Val)) { if (auto *ValVar = llvm::dyn_cast<Variable>(Val)) {
Context.insert(InstFakeUse::create(Func, ValVar)); Context.insert<InstFakeUse>(ValVar);
} }
// The address base (if any) is also reused in the loop. // The address base (if any) is also reused in the loop.
if (Variable *Base = Addr->getBase()) if (Variable *Base = Addr->getBase())
Context.insert(InstFakeUse::create(Func, Base)); Context.insert<InstFakeUse>(Base);
_mov(Dest, T_eax); _mov(Dest, T_eax);
} }
...@@ -4660,8 +4657,7 @@ void TargetX86Base<Machine>::doMockBoundsCheck(Operand *Opnd) { ...@@ -4660,8 +4657,7 @@ void TargetX86Base<Machine>::doMockBoundsCheck(Operand *Opnd) {
if (Var->getRegNum() == Traits::RegisterSet::Reg_esp) if (Var->getRegNum() == Traits::RegisterSet::Reg_esp)
return; return;
typename Traits::Insts::Label *Label = auto *Label = Traits::Insts::Label::create(Func, this);
Traits::Insts::Label::create(Func, this);
_cmp(Opnd, Ctx->getConstantZero(IceType_i32)); _cmp(Opnd, Ctx->getConstantZero(IceType_i32));
_br(Traits::Cond::Br_e, Label); _br(Traits::Cond::Br_e, Label);
_cmp(Opnd, Ctx->getConstantInt32(1)); _cmp(Opnd, Ctx->getConstantInt32(1));
...@@ -4711,7 +4707,7 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() { ...@@ -4711,7 +4707,7 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
} }
Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp, Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp,
Index, Shift, SegmentReg); Index, Shift, SegmentReg);
Context.insert(InstLoad::create(Func, Dest, Addr)); Context.insert<InstLoad>(Dest, Addr);
} }
} }
...@@ -4775,8 +4771,7 @@ void TargetX86Base<Machine>::lowerSelectMove(Variable *Dest, ...@@ -4775,8 +4771,7 @@ void TargetX86Base<Machine>::lowerSelectMove(Variable *Dest,
// The cmov instruction doesn't allow 8-bit or FP operands, so we need // The cmov instruction doesn't allow 8-bit or FP operands, so we need
// explicit control flow. // explicit control flow.
// d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1: // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1:
typename Traits::Insts::Label *Label = auto *Label = Traits::Insts::Label::create(Func, this);
Traits::Insts::Label::create(Func, this);
SrcT = legalize(SrcT, Legal_Reg | Legal_Imm); SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
_mov(Dest, SrcT); _mov(Dest, SrcT);
_br(Cond, Label); _br(Cond, Label);
...@@ -5018,10 +5013,9 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() { ...@@ -5018,10 +5013,9 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
} }
Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp, Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp,
Index, Shift, SegmentReg); Index, Shift, SegmentReg);
auto *NewStore = InstStore::create(Func, Data, Addr); auto *NewStore = Context.insert<InstStore>(Data, Addr);
if (Inst->getDest()) if (Inst->getDest())
NewStore->setRmwBeacon(Inst->getRmwBeacon()); NewStore->setRmwBeacon(Inst->getRmwBeacon());
Context.insert(NewStore);
} }
} }
...@@ -5273,24 +5267,23 @@ void TargetX86Base<Machine>::scalarizeArithmetic(InstArithmetic::OpKind Kind, ...@@ -5273,24 +5267,23 @@ void TargetX86Base<Machine>::scalarizeArithmetic(InstArithmetic::OpKind Kind,
// Extract the next two inputs. // Extract the next two inputs.
Variable *Op0 = Func->makeVariable(ElementTy); Variable *Op0 = Func->makeVariable(ElementTy);
Context.insert(InstExtractElement::create(Func, Op0, Src0, Index)); Context.insert<InstExtractElement>(Op0, Src0, Index);
Variable *Op1 = Func->makeVariable(ElementTy); Variable *Op1 = Func->makeVariable(ElementTy);
Context.insert(InstExtractElement::create(Func, Op1, Src1, Index)); Context.insert<InstExtractElement>(Op1, Src1, Index);
// Perform the arithmetic as a scalar operation. // Perform the arithmetic as a scalar operation.
Variable *Res = Func->makeVariable(ElementTy); Variable *Res = Func->makeVariable(ElementTy);
auto *Arith = InstArithmetic::create(Func, Kind, Res, Op0, Op1); auto *Arith = Context.insert<InstArithmetic>(Kind, Res, Op0, Op1);
Context.insert(Arith);
// We might have created an operation that needed a helper call. // We might have created an operation that needed a helper call.
genTargetHelperCallFor(Arith); genTargetHelperCallFor(Arith);
// Insert the result into position. // Insert the result into position.
Variable *DestT = Func->makeVariable(Ty); Variable *DestT = Func->makeVariable(Ty);
Context.insert(InstInsertElement::create(Func, DestT, T, Res, Index)); Context.insert<InstInsertElement>(DestT, T, Res, Index);
T = DestT; T = DestT;
} }
Context.insert(InstAssign::create(Func, Dest, T)); Context.insert<InstAssign>(Dest, T);
} }
/// The following pattern occurs often in lowered C and C++ code: /// The following pattern occurs often in lowered C and C++ code:
...@@ -5581,7 +5574,7 @@ void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) { ...@@ -5581,7 +5574,7 @@ void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) {
HelperName = H_bitcast_i8_8xi1; HelperName = 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::create(Func, InstCast::Zext, Src0AsI32, Src0)); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
Src0 = Src0AsI32; Src0 = Src0AsI32;
} break; } break;
case IceType_v16i1: { case IceType_v16i1: {
...@@ -5589,7 +5582,7 @@ void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) { ...@@ -5589,7 +5582,7 @@ void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) {
HelperName = H_bitcast_i16_16xi1; HelperName = 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::create(Func, InstCast::Zext, Src0AsI32, Src0)); Context.insert<InstCast>(InstCast::Zext, Src0AsI32, Src0);
Src0 = Src0AsI32; Src0 = Src0AsI32;
} break; } break;
} }
...@@ -5724,13 +5717,13 @@ Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) { ...@@ -5724,13 +5717,13 @@ Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) {
break; break;
case IceType_f32: case IceType_f32:
case IceType_f64: case IceType_f64:
Context.insert(InstFakeDef::create(Func, Reg)); Context.insert<InstFakeDef>(Reg);
_xorps(Reg, Reg); _xorps(Reg, Reg);
break; break;
default: default:
// All vector types use the same pxor instruction. // All vector types use the same pxor instruction.
assert(isVectorType(Ty)); assert(isVectorType(Ty));
Context.insert(InstFakeDef::create(Func, Reg)); Context.insert<InstFakeDef>(Reg);
_pxor(Reg, Reg); _pxor(Reg, Reg);
break; break;
} }
...@@ -5754,7 +5747,7 @@ Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty, ...@@ -5754,7 +5747,7 @@ Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty,
int32_t RegNum) { int32_t RegNum) {
Variable *MinusOnes = makeReg(Ty, RegNum); Variable *MinusOnes = makeReg(Ty, RegNum);
// Insert a FakeDef so the live range of MinusOnes is not overestimated. // Insert a FakeDef so the live range of MinusOnes is not overestimated.
Context.insert(InstFakeDef::create(Func, MinusOnes)); Context.insert<InstFakeDef>(MinusOnes);
_pcmpeq(MinusOnes, MinusOnes); _pcmpeq(MinusOnes, MinusOnes);
return MinusOnes; return MinusOnes;
} }
...@@ -6064,7 +6057,7 @@ Operand *TargetX86Base<Machine>::legalizeUndef(Operand *From, int32_t RegNum) { ...@@ -6064,7 +6057,7 @@ Operand *TargetX86Base<Machine>::legalizeUndef(Operand *From, int32_t RegNum) {
// //
// If in the future the implementation is changed to lower undef values to // If in the future the implementation is changed to lower undef values to
// uninitialized registers, a FakeDef will be needed: // uninitialized registers, a FakeDef will be needed:
// Context.insert(InstFakeDef::create(Func, Reg)); // Context.insert<InstFakeDef>(Reg);
// This is in order to ensure that the live range of Reg is not // This is in order to ensure that the live range of Reg is not
// overestimated. If the constant being lowered is a 64 bit value, then // overestimated. If the constant being lowered is a 64 bit value, then
// the result should be split and the lo and hi components will need to go // the result should be split and the lo and hi components will need to go
......
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