Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Unified Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1216933015: X8632 Templatization completed. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringX86BaseImpl.h
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 6a0f3b3db52dc5f08a053ee7152c0a298ed481b6..68cbf94d26927089062b3c6aab79a9b8f8f6f2eb 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -23,20 +23,16 @@
#include "IceDefs.h"
#include "IceELFObjectWriter.h"
#include "IceGlobalInits.h"
-#include "IceInstX8632.h"
#include "IceLiveness.h"
#include "IceOperand.h"
-#include "IceRegistersX8632.h"
-#include "IceTargetLoweringX8632.def"
-#include "IceTargetLoweringX8632.h"
#include "IceUtils.h"
#include "llvm/Support/MathExtras.h"
namespace Ice {
namespace X86Internal {
-/// A helper class to ease the settings of RandomizationPoolingPause
-/// to disable constant blinding or pooling for some translation phases.
+/// A helper class to ease the settings of RandomizationPoolingPause to disable
+/// constant blinding or pooling for some translation phases.
class BoolFlagSaver {
BoolFlagSaver() = delete;
BoolFlagSaver(const BoolFlagSaver &) = delete;
@@ -85,8 +81,7 @@ public:
};
/// Currently the actual enum values are not used (other than CK_None), but we
- /// go
- /// ahead and produce them anyway for symmetry with the
+ /// go ahead and produce them anyway for symmetry with the
/// BoolFoldingProducerKind.
enum BoolFoldingConsumerKind { CK_None, CK_Br, CK_Select, CK_Sext, CK_Zext };
@@ -163,12 +158,11 @@ BoolFolding<MachineTraits>::getConsumerKind(const Inst *Instr) {
return CK_None;
}
-/// Returns true if the producing instruction has a "complex" lowering
-/// sequence. This generally means that its lowering sequence requires
-/// more than one conditional branch, namely 64-bit integer compares
-/// and some floating-point compares. When this is true, and there is
-/// more than one consumer, we prefer to disable the folding
-/// optimization because it minimizes branches.
+/// Returns true if the producing instruction has a "complex" lowering sequence.
+/// This generally means that its lowering sequence requires more than one
+/// conditional branch, namely 64-bit integer compares and some floating-point
+/// compares. When this is true, and there is more than one consumer, we prefer
+/// to disable the folding optimization because it minimizes branches.
template <class MachineTraits>
bool BoolFolding<MachineTraits>::hasComplexLowering(const Inst *Instr) {
switch (getProducerKind(Instr)) {
@@ -226,10 +220,10 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) {
setInvalid(I.first);
continue;
}
- // Mark as "dead" rather than outright deleting. This is so that
- // other peephole style optimizations during or before lowering
- // have access to this instruction in undeleted form. See for
- // example tryOptimizedCmpxchgCmpBr().
+ // Mark as "dead" rather than outright deleting. This is so that other
+ // peephole style optimizations during or before lowering have access to
+ // this instruction in undeleted form. See for example
+ // tryOptimizedCmpxchgCmpBr().
I.second.Instr->setDead();
}
}
@@ -283,24 +277,18 @@ TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
TargetInstructionSet::X86InstructionSet_Begin) +
Traits::InstructionSet::Begin);
}
- // TODO: Don't initialize IntegerRegisters and friends every time.
- // Instead, initialize in some sort of static initializer for the
- // class.
+ // TODO: Don't initialize IntegerRegisters and friends every time. Instead,
+ // initialize in some sort of static initializer for the class.
llvm::SmallBitVector IntegerRegisters(Traits::RegisterSet::Reg_NUM);
llvm::SmallBitVector IntegerRegistersI8(Traits::RegisterSet::Reg_NUM);
llvm::SmallBitVector FloatRegisters(Traits::RegisterSet::Reg_NUM);
llvm::SmallBitVector VectorRegisters(Traits::RegisterSet::Reg_NUM);
llvm::SmallBitVector InvalidRegisters(Traits::RegisterSet::Reg_NUM);
ScratchRegs.resize(Traits::RegisterSet::Reg_NUM);
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- IntegerRegisters[Traits::RegisterSet::val] = isInt; \
- IntegerRegistersI8[Traits::RegisterSet::val] = isI8; \
- FloatRegisters[Traits::RegisterSet::val] = isFP; \
- VectorRegisters[Traits::RegisterSet::val] = isFP; \
- ScratchRegs[Traits::RegisterSet::val] = scratch;
- REGX8632_TABLE;
-#undef X
+
+ Traits::initRegisterSet(&IntegerRegisters, &IntegerRegistersI8,
+ &FloatRegisters, &VectorRegisters, &ScratchRegs);
+
TypeToRegisterSet[IceType_void] = InvalidRegisters;
TypeToRegisterSet[IceType_i1] = IntegerRegistersI8;
TypeToRegisterSet[IceType_i8] = IntegerRegistersI8;
@@ -348,19 +336,18 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
// Argument lowering
Func->doArgLowering();
- // Target lowering. This requires liveness analysis for some parts
- // of the lowering decisions, such as compare/branch fusing. If
- // non-lightweight liveness analysis is used, the instructions need
- // to be renumbered first. TODO: This renumbering should only be
- // necessary if we're actually calculating live intervals, which we
- // only do for register allocation.
+ // Target lowering. This requires liveness analysis for some parts of the
+ // lowering decisions, such as compare/branch fusing. If non-lightweight
+ // liveness analysis is used, the instructions need to be renumbered first
+ // TODO: This renumbering should only be necessary if we're actually
+ // calculating live intervals, which we only do for register allocation.
Func->renumberInstructions();
if (Func->hasError())
return;
- // TODO: It should be sufficient to use the fastest liveness
- // calculation, i.e. livenessLightweight(). However, for some
- // reason that slows down the rest of the translation. Investigate.
+ // TODO: It should be sufficient to use the fastest liveness calculation, i.e.
+ // livenessLightweight(). However, for some reason that slows down the rest
+ // of the translation. Investigate.
Func->liveness(Liveness_Basic);
if (Func->hasError())
return;
@@ -376,19 +363,19 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
return;
Func->dump("After x86 codegen");
- // Register allocation. This requires instruction renumbering and
- // full liveness analysis.
+ // Register allocation. This requires instruction renumbering and full
+ // liveness analysis.
Func->renumberInstructions();
if (Func->hasError())
return;
Func->liveness(Liveness_Intervals);
if (Func->hasError())
return;
- // Validate the live range computations. The expensive validation
- // call is deliberately only made when assertions are enabled.
+ // Validate the live range computations. The expensive validation call is
+ // deliberately only made when assertions are enabled.
assert(Func->validateLiveness());
- // The post-codegen dump is done here, after liveness analysis and
- // associated cleanup, to make the dump cleaner and more useful.
+ // The post-codegen dump is done here, after liveness analysis and associated
+ // cleanup, to make the dump cleaner and more useful.
Func->dump("After initial x8632 codegen");
Func->getVMetadata()->init(VMK_All);
regAlloc(RAK_Global);
@@ -397,9 +384,9 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->dump("After linear scan regalloc");
if (Ctx->getFlags().getPhiEdgeSplit()) {
- // We need to pause constant blinding or pooling during advanced
- // phi lowering, unless the lowering assignment has a physical
- // register for the dest Variable.
+ // We need to pause constant blinding or pooling during advanced phi
+ // lowering, unless the lowering assignment has a physical register for the
+ // dest Variable.
{
BoolFlagSaver B(RandomizationPoolingPaused, true);
Func->advancedPhiLowering();
@@ -416,11 +403,10 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->contractEmptyNodes();
Func->reorderNodes();
- // Branch optimization. This needs to be done just before code
- // emission. In particular, no transformations that insert or
- // reorder CfgNodes should be done after branch optimization. We go
- // ahead and do it before nop insertion to reduce the amount of work
- // needed for searching for opportunities.
+ // Branch optimization. This needs to be done just before code emission. In
+ // particular, no transformations that insert or reorder CfgNodes should be
+ // done after branch optimization. We go ahead and do it before nop insertion
+ // to reduce the amount of work needed for searching for opportunities.
Func->doBranchOpt();
Func->dump("After branch optimization");
@@ -468,8 +454,7 @@ template <class Machine> void TargetX86Base<Machine>::translateOm1() {
bool canRMW(const InstArithmetic *Arith) {
Type Ty = Arith->getDest()->getType();
- // X86 vector instructions write to a register and have no RMW
- // option.
+ // X86 vector instructions write to a register and have no RMW option.
if (isVectorType(Ty))
return false;
bool isI64 = Ty == IceType_i64;
@@ -496,11 +481,14 @@ bool canRMW(const InstArithmetic *Arith) {
}
}
+template <class Machine>
bool isSameMemAddressOperand(const Operand *A, const Operand *B) {
if (A == B)
return true;
- if (auto *MemA = llvm::dyn_cast<OperandX8632Mem>(A)) {
- if (auto *MemB = llvm::dyn_cast<OperandX8632Mem>(B)) {
+ if (auto *MemA = llvm::dyn_cast<
+ typename TargetX86Base<Machine>::Traits::X86OperandMem>(A)) {
+ if (auto *MemB = llvm::dyn_cast<
+ typename TargetX86Base<Machine>::Traits::X86OperandMem>(B)) {
return MemA->getBase() == MemB->getBase() &&
MemA->getOffset() == MemB->getOffset() &&
MemA->getIndex() == MemB->getIndex() &&
@@ -565,8 +553,8 @@ template <class Machine> void TargetX86Base<Machine>::findRMW() {
// still trigger, resulting in two loads and one store, which is
// worse than the original one load and one store. However, this is
// probably rare, and caching probably keeps it just as fast.
- if (!isSameMemAddressOperand(Load->getSourceAddress(),
- Store->getAddr()))
+ if (!isSameMemAddressOperand<Machine>(Load->getSourceAddress(),
+ Store->getAddr()))
continue;
Operand *ArithSrcFromLoad = Arith->getSrc(0);
Operand *ArithSrcOther = Arith->getSrc(1);
@@ -593,7 +581,7 @@ template <class Machine> void TargetX86Base<Machine>::findRMW() {
Store->setRmwBeacon(Beacon);
InstFakeDef *BeaconDef = InstFakeDef::create(Func, Beacon);
Node->getInsts().insert(I3, BeaconDef);
- InstX8632FakeRMW *RMW = InstX8632FakeRMW::create(
+ auto *RMW = Traits::Insts::FakeRMW::create(
Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp());
Node->getInsts().insert(I3, RMW);
}
@@ -721,22 +709,13 @@ template <class Machine> void TargetX86Base<Machine>::doLoadOpt() {
template <class Machine>
bool TargetX86Base<Machine>::doBranchOpt(Inst *I, const CfgNode *NextNode) {
- if (InstX8632Br *Br = llvm::dyn_cast<InstX8632Br>(I)) {
+ if (auto *Br = llvm::dyn_cast<typename Traits::Insts::Br>(I)) {
return Br->optimizeBranch(NextNode);
}
return false;
}
template <class Machine>
-IceString TargetX86Base<Machine>::RegNames[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- name,
- REGX8632_TABLE
-#undef X
-};
-
-template <class Machine>
Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
if (Ty == IceType_void)
Ty = IceType_i32;
@@ -760,30 +739,7 @@ Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
template <class Machine>
IceString TargetX86Base<Machine>::getRegName(SizeT RegNum, Type Ty) const {
- assert(RegNum < Traits::RegisterSet::Reg_NUM);
- static IceString RegNames8[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- name8,
- REGX8632_TABLE
-#undef X
- };
- static IceString RegNames16[] = {
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- name16,
- REGX8632_TABLE
-#undef X
- };
- switch (Ty) {
- case IceType_i1:
- case IceType_i8:
- return RegNames8[RegNum];
- case IceType_i16:
- return RegNames16[RegNum];
- default:
- return RegNames[RegNum];
- }
+ return Traits::getRegName(RegNum, Ty);
}
template <class Machine>
@@ -884,17 +840,16 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
if (Arg->hasReg()) {
assert(Ty != IceType_i64);
- OperandX8632Mem *Mem = OperandX8632Mem::create(
+ typename Traits::X86OperandMem *Mem = Traits::X86OperandMem::create(
Func, Ty, FramePtr, Ctx->getConstantInt32(Arg->getStackOffset()));
if (isVectorType(Arg->getType())) {
_movp(Arg, Mem);
} else {
_mov(Arg, Mem);
}
- // This argument-copying instruction uses an explicit
- // OperandX8632Mem operand instead of a Variable, so its
- // fill-from-stack operation has to be tracked separately for
- // statistics.
+ // This argument-copying instruction uses an explicit Traits::X86OperandMem
+ // operand instead of a Variable, so its fill-from-stack operation has to be
+ // tracked separately for statistics.
Ctx->statsUpdateFills();
}
}
@@ -965,7 +920,8 @@ template <class Machine> void TargetX86Base<Machine>::addProlog(CfgNode *Node) {
// that stack slot.
std::function<bool(Variable *)> TargetVarHook =
[&VariablesLinkedToSpillSlots](Variable *Var) {
- if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) {
+ if (auto *SpillVar =
+ llvm::dyn_cast<typename Traits::SpillVariable>(Var)) {
assert(Var->getWeight().isZero());
if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
VariablesLinkedToSpillSlots.push_back(Var);
@@ -1069,7 +1025,8 @@ template <class Machine> void TargetX86Base<Machine>::addProlog(CfgNode *Node) {
// Assign stack offsets to variables that have been linked to spilled
// variables.
for (Variable *Var : VariablesLinkedToSpillSlots) {
- Variable *Linked = (llvm::cast<SpillVariable>(Var))->getLinkedTo();
+ Variable *Linked =
+ (llvm::cast<typename Traits::SpillVariable>(Var))->getLinkedTo();
Var->setStackOffset(Linked->getStackOffset());
}
this->HasComputedFrame = true;
@@ -1106,7 +1063,7 @@ template <class Machine> void TargetX86Base<Machine>::addEpilog(CfgNode *Node) {
InstList &Insts = Node->getInsts();
InstList::reverse_iterator RI, E;
for (RI = Insts.rbegin(), E = Insts.rend(); RI != E; ++RI) {
- if (llvm::isa<InstX8632Ret>(*RI))
+ if (llvm::isa<typename Traits::Insts::Ret>(*RI))
break;
}
if (RI == E)
@@ -1216,8 +1173,8 @@ Operand *TargetX86Base<Machine>::loOperand(Operand *Operand) {
Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue())));
return legalize(ConstInt);
}
- if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
- OperandX8632Mem *MemOperand = OperandX8632Mem::create(
+ if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
+ auto *MemOperand = Traits::X86OperandMem::create(
Func, IceType_i32, Mem->getBase(), Mem->getOffset(), Mem->getIndex(),
Mem->getShift(), Mem->getSegmentRegister());
// Test if we should randomize or pool the offset, if so randomize it or
@@ -1245,7 +1202,7 @@ Operand *TargetX86Base<Machine>::hiOperand(Operand *Operand) {
// check if we need to blind/pool the constant
return legalize(ConstInt);
}
- if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
+ if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
Constant *Offset = Mem->getOffset();
if (Offset == nullptr) {
Offset = Ctx->getConstantInt32(4);
@@ -1259,7 +1216,7 @@ Operand *TargetX86Base<Machine>::hiOperand(Operand *Operand) {
Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
SymOffset->getSuppressMangling());
}
- OperandX8632Mem *MemOperand = OperandX8632Mem::create(
+ auto *MemOperand = Traits::X86OperandMem::create(
Func, IceType_i32, Mem->getBase(), Offset, Mem->getIndex(),
Mem->getShift(), Mem->getSegmentRegister());
// Test if the Offset is an eligible i32 constants for randomization and
@@ -1275,32 +1232,7 @@ template <class Machine>
llvm::SmallBitVector
TargetX86Base<Machine>::getRegisterSet(RegSetMask Include,
RegSetMask Exclude) const {
- llvm::SmallBitVector Registers(Traits::RegisterSet::Reg_NUM);
-
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- if (scratch && (Include & RegSet_CallerSave)) \
- Registers[Traits::RegisterSet::val] = true; \
- if (preserved && (Include & RegSet_CalleeSave)) \
- Registers[Traits::RegisterSet::val] = true; \
- if (stackptr && (Include & RegSet_StackPointer)) \
- Registers[Traits::RegisterSet::val] = true; \
- if (frameptr && (Include & RegSet_FramePointer)) \
- Registers[Traits::RegisterSet::val] = true; \
- if (scratch && (Exclude & RegSet_CallerSave)) \
- Registers[Traits::RegisterSet::val] = false; \
- if (preserved && (Exclude & RegSet_CalleeSave)) \
- Registers[Traits::RegisterSet::val] = false; \
- if (stackptr && (Exclude & RegSet_StackPointer)) \
- Registers[Traits::RegisterSet::val] = false; \
- if (frameptr && (Exclude & RegSet_FramePointer)) \
- Registers[Traits::RegisterSet::val] = false;
-
- REGX8632_TABLE
-
-#undef X
-
- return Registers;
+ return Traits::getRegisterSet(Include, Exclude);
}
template <class Machine>
@@ -1423,17 +1355,20 @@ bool TargetX86Base<Machine>::optimizeScalarMul(Variable *Dest, Operand *Src0,
Constant *Zero = Ctx->getConstantZero(IceType_i32);
for (uint32_t i = 0; i < Count9; ++i) {
const uint16_t Shift = 3; // log2(9-1)
- _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T,
+ Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
_set_dest_nonkillable();
}
for (uint32_t i = 0; i < Count5; ++i) {
const uint16_t Shift = 2; // log2(5-1)
- _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T,
+ Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
_set_dest_nonkillable();
}
for (uint32_t i = 0; i < Count3; ++i) {
const uint16_t Shift = 1; // log2(3-1)
- _lea(T, OperandX8632Mem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T,
+ Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
_set_dest_nonkillable();
}
if (Count2) {
@@ -1601,7 +1536,8 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
Constant *BitTest = Ctx->getConstantInt32(0x20);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
_mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
_mov(T_2, Src0Lo);
_mov(T_3, Src0Hi);
@@ -1636,7 +1572,8 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
Constant *BitTest = Ctx->getConstantInt32(0x20);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
_mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
_mov(T_2, Src0Lo);
_mov(T_3, Src0Hi);
@@ -1671,7 +1608,8 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
Constant *BitTest = Ctx->getConstantInt32(0x20);
Constant *SignExtend = Ctx->getConstantInt32(0x1f);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
_mov(T_1, Src1Lo, Traits::RegisterSet::Reg_ecx);
_mov(T_2, Src0Lo);
_mov(T_3, Src0Hi);
@@ -1709,7 +1647,7 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
if (isVectorType(Dest->getType())) {
// TODO: Trap on integer divide and integer modulo by zero.
// See: https://code.google.com/p/nativeclient/issues/detail?id=3899
- if (llvm::isa<OperandX8632Mem>(Src1))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1))
Src1 = legalizeToVar(Src1);
switch (Inst->getOp()) {
case InstArithmetic::_num:
@@ -2208,7 +2146,8 @@ void TargetX86Base<Machine>::lowerCall(const InstCall *Instr) {
Variable *esp =
Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp);
Constant *Loc = Ctx->getConstantInt32(ParameterAreaSizeBytes);
- StackArgLocations.push_back(OperandX8632Mem::create(Func, Ty, esp, Loc));
+ StackArgLocations.push_back(
+ Traits::X86OperandMem::create(Func, Ty, esp, Loc));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType());
}
}
@@ -2305,7 +2244,7 @@ void TargetX86Base<Machine>::lowerCall(const InstCall *Instr) {
CallTarget = CallTargetVar;
}
}
- Inst *NewCall = InstX8632Call::create(Func, ReturnReg, CallTarget);
+ Inst *NewCall = Traits::Insts::Call::create(Func, ReturnReg, CallTarget);
Context.insert(NewCall);
if (NeedSandboxing)
_bundle_unlock();
@@ -2532,7 +2471,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
// t1 = cvt Src0RM; Dest = t1
Variable *T = makeReg(Dest->getType());
- _cvt(T, Src0RM, InstX8632Cvt::Float2float);
+ _cvt(T, Src0RM, Traits::Insts::Cvt::Float2float);
_mov(Dest, T);
break;
}
@@ -2541,10 +2480,10 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
assert(Dest->getType() == IceType_v4i32 &&
Inst->getSrc(0)->getType() == IceType_v4f32);
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
- if (llvm::isa<OperandX8632Mem>(Src0RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
Src0RM = legalizeToVar(Src0RM);
Variable *T = makeReg(Dest->getType());
- _cvt(T, Src0RM, InstX8632Cvt::Tps2dq);
+ _cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
_movp(Dest, T);
} else if (Dest->getType() == IceType_i64) {
// Use a helper for converting floating-point values to 64-bit
@@ -2567,7 +2506,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
Variable *T_1 = makeReg(IceType_i32);
Variable *T_2 = makeReg(Dest->getType());
- _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
+ _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt1(1));
@@ -2606,7 +2545,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
Variable *T_1 = makeReg(IceType_i32);
Variable *T_2 = makeReg(Dest->getType());
- _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
+ _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt1(1));
@@ -2618,10 +2557,10 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
assert(Dest->getType() == IceType_v4f32 &&
Inst->getSrc(0)->getType() == IceType_v4i32);
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
- if (llvm::isa<OperandX8632Mem>(Src0RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
Src0RM = legalizeToVar(Src0RM);
Variable *T = makeReg(Dest->getType());
- _cvt(T, Src0RM, InstX8632Cvt::Dq2ps);
+ _cvt(T, Src0RM, Traits::Insts::Cvt::Dq2ps);
_movp(Dest, T);
} else if (Inst->getSrc(0)->getType() == IceType_i64) {
// Use a helper for x86-32.
@@ -2645,7 +2584,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
_mov(T_1, Src0RM);
else
_movsx(T_1, Src0RM);
- _cvt(T_2, T_1, InstX8632Cvt::Si2ss);
+ _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
_mov(Dest, T_2);
}
break;
@@ -2686,7 +2625,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
_mov(T_1, Src0RM);
else
_movzx(T_1, Src0RM);
- _cvt(T_2, T_1, InstX8632Cvt::Si2ss);
+ _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
_mov(Dest, T_2);
}
break;
@@ -2728,8 +2667,8 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
Variable *T = nullptr;
// TODO: Should be able to force a spill setup by calling legalize() with
// Legal_Mem and not Legal_Reg or Legal_Imm.
- SpillVariable *SpillVar =
- Func->template makeVariable<SpillVariable>(SrcType);
+ typename Traits::SpillVariable *SpillVar =
+ Func->template makeVariable<typename Traits::SpillVariable>(SrcType);
SpillVar->setLinkedTo(Dest);
Variable *Spill = SpillVar;
Spill->setWeight(RegWeight::Zero);
@@ -2748,14 +2687,17 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// a_hi.i32 = t_hi.i32
Operand *SpillLo, *SpillHi;
if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
- SpillVariable *SpillVar =
- Func->template makeVariable<SpillVariable>(IceType_f64);
+ typename Traits::SpillVariable *SpillVar =
+ Func->template makeVariable<typename Traits::SpillVariable>(
+ IceType_f64);
SpillVar->setLinkedTo(Src0Var);
Variable *Spill = SpillVar;
Spill->setWeight(RegWeight::Zero);
_movq(Spill, Src0RM);
- SpillLo = VariableSplit::create(Func, Spill, VariableSplit::Low);
- SpillHi = VariableSplit::create(Func, Spill, VariableSplit::High);
+ SpillLo = Traits::VariableSplit::create(Func, Spill,
+ Traits::VariableSplit::Low);
+ SpillHi = Traits::VariableSplit::create(Func, Spill,
+ Traits::VariableSplit::High);
} else {
SpillLo = loOperand(Src0RM);
SpillHi = hiOperand(Src0RM);
@@ -2774,7 +2716,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
case IceType_f64: {
Src0 = legalize(Src0);
assert(Src0->getType() == IceType_i64);
- if (llvm::isa<OperandX8632Mem>(Src0)) {
+ if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
Variable *T = Func->template makeVariable(Dest->getType());
_movq(T, Src0);
_movq(Dest, T);
@@ -2787,17 +2729,18 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// t_hi.i32 = b_hi.i32
// hi(s.f64) = t_hi.i32
// a.f64 = s.f64
- SpillVariable *SpillVar =
- Func->template makeVariable<SpillVariable>(IceType_f64);
+ typename Traits::SpillVariable *SpillVar =
+ Func->template makeVariable<typename Traits::SpillVariable>(
+ IceType_f64);
SpillVar->setLinkedTo(Dest);
Variable *Spill = SpillVar;
Spill->setWeight(RegWeight::Zero);
Variable *T_Lo = nullptr, *T_Hi = nullptr;
- VariableSplit *SpillLo =
- VariableSplit::create(Func, Spill, VariableSplit::Low);
- VariableSplit *SpillHi =
- VariableSplit::create(Func, Spill, VariableSplit::High);
+ typename Traits::VariableSplit *SpillLo = Traits::VariableSplit::create(
+ Func, Spill, Traits::VariableSplit::Low);
+ typename Traits::VariableSplit *SpillHi = Traits::VariableSplit::create(
+ Func, Spill, Traits::VariableSplit::High);
_mov(T_Lo, loOperand(Src0));
// Technically, the Spill is defined after the _store happens, but
// SpillLo is considered a "use" of Spill so define Spill before it
@@ -2897,7 +2840,7 @@ void TargetX86Base<Machine>::lowerExtractElement(
// Compute the location of the element in memory.
unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
- OperandX8632Mem *Loc =
+ typename Traits::X86OperandMem *Loc =
getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
_mov(ExtractedElementR, Loc);
}
@@ -2943,7 +2886,7 @@ void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Inst) {
} else {
Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
- if (llvm::isa<OperandX8632Mem>(Src1RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
Src1RM = legalizeToVar(Src1RM);
switch (Condition) {
@@ -3018,7 +2961,8 @@ void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Inst) {
Constant *Default = Ctx->getConstantInt32(Traits::TableFcmp[Index].Default);
_mov(Dest, Default);
if (HasC1) {
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
_br(Traits::TableFcmp[Index].C1, Label);
if (HasC2) {
_br(Traits::TableFcmp[Index].C2, Label);
@@ -3091,13 +3035,13 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
llvm_unreachable("unexpected condition");
break;
case InstIcmp::Eq: {
- if (llvm::isa<OperandX8632Mem>(Src1RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
Src1RM = legalizeToVar(Src1RM);
_movp(T, Src0RM);
_pcmpeq(T, Src1RM);
} break;
case InstIcmp::Ne: {
- if (llvm::isa<OperandX8632Mem>(Src1RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
Src1RM = legalizeToVar(Src1RM);
_movp(T, Src0RM);
_pcmpeq(T, Src1RM);
@@ -3106,7 +3050,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
} break;
case InstIcmp::Ugt:
case InstIcmp::Sgt: {
- if (llvm::isa<OperandX8632Mem>(Src1RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
Src1RM = legalizeToVar(Src1RM);
_movp(T, Src0RM);
_pcmpgt(T, Src1RM);
@@ -3114,7 +3058,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
case InstIcmp::Uge:
case InstIcmp::Sge: {
// !(Src1RM > Src0RM)
- if (llvm::isa<OperandX8632Mem>(Src0RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
Src0RM = legalizeToVar(Src0RM);
_movp(T, Src1RM);
_pcmpgt(T, Src0RM);
@@ -3123,7 +3067,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
} break;
case InstIcmp::Ult:
case InstIcmp::Slt: {
- if (llvm::isa<OperandX8632Mem>(Src0RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
Src0RM = legalizeToVar(Src0RM);
_movp(T, Src1RM);
_pcmpgt(T, Src0RM);
@@ -3131,7 +3075,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
case InstIcmp::Ule:
case InstIcmp::Sle: {
// !(Src0RM > Src1RM)
- if (llvm::isa<OperandX8632Mem>(Src1RM))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
Src1RM = legalizeToVar(Src1RM);
_movp(T, Src0RM);
_pcmpgt(T, Src1RM);
@@ -3156,8 +3100,10 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
Constant *One = Ctx->getConstantInt32(1);
- InstX8632Label *LabelFalse = InstX8632Label::create(Func, this);
- InstX8632Label *LabelTrue = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *LabelFalse =
+ Traits::Insts::Label::create(Func, this);
+ typename Traits::Insts::Label *LabelTrue =
+ Traits::Insts::Label::create(Func, this);
_mov(Dest, One);
_cmp(Src0HiRM, Src1HiRI);
if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None)
@@ -3293,7 +3239,7 @@ void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) {
// Compute the location of the position to insert in memory.
unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
- OperandX8632Mem *Loc =
+ typename Traits::X86OperandMem *Loc =
getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
_store(legalizeToVar(ElementToInsertNotLegalized), Loc);
@@ -3383,7 +3329,8 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
// can't happen anyway, since this is x86-32 and integer arithmetic only
// happens on 32-bit quantities.
Variable *T = makeReg(IceType_f64);
- OperandX8632Mem *Addr = formMemoryOperand(Instr->getArg(0), IceType_f64);
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Instr->getArg(0), IceType_f64);
_movq(T, Addr);
// Then cast the bits back out of the XMM register to the i64 Dest.
InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
@@ -3433,7 +3380,8 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, T, Value);
lowerCast(Cast);
// Then store XMM w/ a movq.
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, IceType_f64);
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, IceType_f64);
_storeq(T, Addr);
_mfence();
return;
@@ -3535,7 +3483,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
// The pand instruction operates on an m128 memory operand, so if
// Src is an f32 or f64, we need to make sure it's in a register.
if (isVectorType(Ty)) {
- if (llvm::isa<OperandX8632Mem>(Src))
+ if (llvm::isa<typename Traits::X86OperandMem>(Src))
Src = legalizeToVar(Src);
} else {
Src = legalizeToVar(Src);
@@ -3590,9 +3538,9 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
case Intrinsics::NaClReadTP: {
if (Ctx->getFlags().getUseSandboxing()) {
Constant *Zero = Ctx->getConstantZero(IceType_i32);
- Operand *Src =
- OperandX8632Mem::create(Func, IceType_i32, nullptr, Zero, nullptr, 0,
- OperandX8632Mem::SegReg_GS);
+ Operand *Src = Traits::X86OperandMem::create(
+ Func, IceType_i32, nullptr, Zero, nullptr, 0,
+ Traits::X86OperandMem::SegReg_GS);
Variable *Dest = Instr->getDest();
Variable *T = nullptr;
_mov(T, Src);
@@ -3655,7 +3603,8 @@ void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
_mov(T_edx, hiOperand(Expected));
_mov(T_ebx, loOperand(Desired));
_mov(T_ecx, hiOperand(Desired));
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Expected->getType());
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, Expected->getType());
const bool Locked = true;
_cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
Variable *DestLo = llvm::cast<Variable>(loOperand(DestPrev));
@@ -3666,7 +3615,8 @@ void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
}
Variable *T_eax = makeReg(Expected->getType(), Traits::RegisterSet::Reg_eax);
_mov(T_eax, Expected);
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Expected->getType());
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, Expected->getType());
Variable *DesiredReg = legalizeToVar(Desired);
const bool Locked = true;
_cmpxchg(Addr, T_eax, DesiredReg, Locked);
@@ -3768,7 +3718,8 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
Op_Hi = &TargetX86Base<Machine>::_adc;
break;
}
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, Dest->getType());
const bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
@@ -3783,7 +3734,8 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
Op_Hi = &TargetX86Base<Machine>::_sbb;
break;
}
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, Dest->getType());
const bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
@@ -3821,7 +3773,8 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
Op_Hi = nullptr;
break;
}
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Dest->getType());
+ typename Traits::X86OperandMem *Addr =
+ formMemoryOperand(Ptr, Dest->getType());
Variable *T = nullptr;
_mov(T, Val);
_xchg(Addr, T);
@@ -3869,12 +3822,13 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
if (Ty == IceType_i64) {
Variable *T_edx = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Ty);
+ typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
_mov(T_eax, loOperand(Addr));
_mov(T_edx, hiOperand(Addr));
Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
Variable *T_ebx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ebx);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
const bool IsXchg8b = Op_Lo == nullptr && Op_Hi == nullptr;
if (!IsXchg8b) {
Context.insert(Label);
@@ -3916,10 +3870,11 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
_mov(DestHi, T_edx);
return;
}
- OperandX8632Mem *Addr = formMemoryOperand(Ptr, Ty);
+ typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
Variable *T_eax = makeReg(Ty, Traits::RegisterSet::Reg_eax);
_mov(T_eax, Addr);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
Context.insert(Label);
// We want to pick a different register for T than Eax, so don't use
// _mov(T == nullptr, T_eax).
@@ -4260,11 +4215,11 @@ void computeAddressOpt(Cfg *Func, const Inst *Instr, Variable *&Base,
template <class Machine>
void TargetX86Base<Machine>::lowerLoad(const InstLoad *Load) {
- // A Load instruction can be treated the same as an Assign
- // instruction, after the source operand is transformed into an
- // OperandX8632Mem operand. Note that the address mode
- // optimization already creates an OperandX8632Mem operand, so it
- // doesn't need another level of transformation.
+ // A Load instruction can be treated the same as an Assign instruction, after
+ // the source operand is transformed into an Traits::X86OperandMem operand.
+ // Note that the address mode optimization already creates an
+ // Traits::X86OperandMem operand, so it doesn't need another level of
+ // transformation.
Variable *DestLoad = Load->getDest();
Type Ty = DestLoad->getType();
Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty);
@@ -4279,19 +4234,19 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
Variable *Index = nullptr;
uint16_t Shift = 0;
int32_t Offset = 0; // TODO: make Constant
- // Vanilla ICE load instructions should not use the segment registers,
- // and computeAddressOpt only works at the level of Variables and Constants,
- // not other OperandX8632Mem, so there should be no mention of segment
+ // Vanilla ICE load instructions should not use the segment registers, and
+ // computeAddressOpt only works at the level of Variables and Constants, not
+ // other Traits::X86OperandMem, so there should be no mention of segment
// registers there either.
- const OperandX8632Mem::SegmentRegisters SegmentReg =
- OperandX8632Mem::DefaultSegment;
+ const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
+ Traits::X86OperandMem::DefaultSegment;
Variable *Base = llvm::dyn_cast<Variable>(Addr);
computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
if (Base && Addr != Base) {
Inst->setDeleted();
Constant *OffsetOp = Ctx->getConstantInt32(Offset);
- Addr = OperandX8632Mem::create(Func, Dest->getType(), Base, OffsetOp, Index,
- Shift, SegmentReg);
+ Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp,
+ Index, Shift, SegmentReg);
Context.insert(InstLoad::create(Func, Dest, Addr));
}
}
@@ -4438,7 +4393,8 @@ void TargetX86Base<Machine>::lowerSelect(const InstSelect *Inst) {
// The cmov instruction doesn't allow 8-bit or FP operands, so
// we need explicit control flow.
// d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1:
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
_mov(Dest, SrcT);
_br(Cond, Label);
@@ -4453,7 +4409,7 @@ void TargetX86Base<Machine>::lowerSelect(const InstSelect *Inst) {
// mov t, SrcT; cmov_!cond t, SrcF; mov dest, t
if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) {
std::swap(SrcT, SrcF);
- Cond = InstX8632::getOppositeCondition(Cond);
+ Cond = InstX86Base<Machine>::getOppositeCondition(Cond);
}
if (DestTy == IceType_i64) {
// Set the low portion.
@@ -4488,15 +4444,18 @@ template <class Machine>
void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) {
Operand *Value = Inst->getData();
Operand *Addr = Inst->getAddr();
- OperandX8632Mem *NewAddr = formMemoryOperand(Addr, Value->getType());
+ typename Traits::X86OperandMem *NewAddr =
+ formMemoryOperand(Addr, Value->getType());
Type Ty = NewAddr->getType();
if (Ty == IceType_i64) {
Value = legalize(Value);
Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm);
Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm);
- _store(ValueHi, llvm::cast<OperandX8632Mem>(hiOperand(NewAddr)));
- _store(ValueLo, llvm::cast<OperandX8632Mem>(loOperand(NewAddr)));
+ _store(ValueHi,
+ llvm::cast<typename Traits::X86OperandMem>(hiOperand(NewAddr)));
+ _store(ValueLo,
+ llvm::cast<typename Traits::X86OperandMem>(loOperand(NewAddr)));
} else if (isVectorType(Ty)) {
_storep(legalizeToVar(Value), NewAddr);
} else {
@@ -4513,18 +4472,18 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
uint16_t Shift = 0;
int32_t Offset = 0; // TODO: make Constant
Variable *Base = llvm::dyn_cast<Variable>(Addr);
- // Vanilla ICE store instructions should not use the segment registers,
- // and computeAddressOpt only works at the level of Variables and Constants,
- // not other OperandX8632Mem, so there should be no mention of segment
+ // Vanilla ICE store instructions should not use the segment registers, and
+ // computeAddressOpt only works at the level of Variables and Constants, not
+ // other Traits::X86OperandMem, so there should be no mention of segment
// registers there either.
- const OperandX8632Mem::SegmentRegisters SegmentReg =
- OperandX8632Mem::DefaultSegment;
+ const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
+ Traits::X86OperandMem::DefaultSegment;
computeAddressOpt(Func, Inst, Base, Index, Shift, Offset);
if (Base && Addr != Base) {
Inst->setDeleted();
Constant *OffsetOp = Ctx->getConstantInt32(Offset);
- Addr = OperandX8632Mem::create(Func, Data->getType(), Base, OffsetOp, Index,
- Shift, SegmentReg);
+ Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp,
+ Index, Shift, SegmentReg);
InstStore *NewStore = InstStore::create(Func, Data, Addr);
if (Inst->getDest())
NewStore->setRmwBeacon(Inst->getRmwBeacon());
@@ -4552,7 +4511,8 @@ void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) {
for (SizeT I = 0; I < NumCases; ++I) {
Constant *ValueLo = Ctx->getConstantInt32(Inst->getValue(I));
Constant *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32);
- InstX8632Label *Label = InstX8632Label::create(Func, this);
+ typename Traits::Insts::Label *Label =
+ Traits::Insts::Label::create(Func, this);
_cmp(Src0Lo, ValueLo);
_br(Traits::Cond::Br_ne, Label);
_cmp(Src0Hi, ValueHi);
@@ -4639,7 +4599,8 @@ void TargetX86Base<Machine>::lowerUnreachable(
}
template <class Machine>
-void TargetX86Base<Machine>::lowerRMW(const InstX8632FakeRMW *RMW) {
+void TargetX86Base<Machine>::lowerRMW(
+ const typename Traits::Insts::FakeRMW *RMW) {
// If the beacon variable's live range does not end in this
// instruction, then it must end in the modified Store instruction
// that follows. This means that the original Store instruction is
@@ -4651,12 +4612,14 @@ void TargetX86Base<Machine>::lowerRMW(const InstX8632FakeRMW *RMW) {
return;
Operand *Src = RMW->getData();
Type Ty = Src->getType();
- OperandX8632Mem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
+ typename Traits::X86OperandMem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
if (Ty == IceType_i64) {
Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm);
Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm);
- OperandX8632Mem *AddrLo = llvm::cast<OperandX8632Mem>(loOperand(Addr));
- OperandX8632Mem *AddrHi = llvm::cast<OperandX8632Mem>(hiOperand(Addr));
+ typename Traits::X86OperandMem *AddrLo =
+ llvm::cast<typename Traits::X86OperandMem>(loOperand(Addr));
+ typename Traits::X86OperandMem *AddrHi =
+ llvm::cast<typename Traits::X86OperandMem>(hiOperand(Addr));
switch (RMW->getOp()) {
default:
// TODO(stichnot): Implement other arithmetic operators.
@@ -4715,7 +4678,8 @@ void TargetX86Base<Machine>::lowerRMW(const InstX8632FakeRMW *RMW) {
template <class Machine>
void TargetX86Base<Machine>::lowerOther(const Inst *Instr) {
- if (const auto *RMW = llvm::dyn_cast<InstX8632FakeRMW>(Instr)) {
+ if (const auto *RMW =
+ llvm::dyn_cast<typename Traits::Insts::FakeRMW>(Instr)) {
lowerRMW(RMW);
} else {
TargetLowering::lowerOther(Instr);
@@ -4991,7 +4955,7 @@ Variable *TargetX86Base<Machine>::makeVectorOfFabsMask(Type Ty,
}
template <class Machine>
-OperandX8632Mem *
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
uint32_t Offset) {
// Ensure that Loc is a stack slot.
@@ -5005,7 +4969,7 @@ TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
Variable *Loc = makeReg(PointerType);
_lea(Loc, Slot);
Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
- return OperandX8632Mem::create(Func, Ty, Loc, ConstantOffset);
+ return Traits::X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
}
/// Helper for legalize() to emit the right code to lower an operand to a
@@ -5037,7 +5001,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
// or in ecx.)
assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg);
- if (auto Mem = llvm::dyn_cast<OperandX8632Mem>(From)) {
+ if (auto Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(From)) {
// Before doing anything with a Mem operand, we need to ensure
// that the Base and Index components are in physical registers.
Variable *Base = Mem->getBase();
@@ -5051,9 +5015,9 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
RegIndex = legalizeToVar(Index);
}
if (Base != RegBase || Index != RegIndex) {
- Mem =
- OperandX8632Mem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
- Mem->getShift(), Mem->getSegmentRegister());
+ Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(),
+ RegIndex, Mem->getShift(),
+ Mem->getSegmentRegister());
}
// For all Memory Operands, we do randomization/pooling here
@@ -5103,7 +5067,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf);
llvm::cast<Constant>(From)->setShouldBePooled(true);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
- From = OperandX8632Mem::create(Func, Ty, Base, Offset);
+ From = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
}
bool NeedsReg = false;
if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
@@ -5162,13 +5126,13 @@ Operand *TargetX86Base<Machine>::legalizeSrc0ForCmp(Operand *Src0,
}
template <class Machine>
-OperandX8632Mem *TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd,
- Type Ty,
- bool DoLegalize) {
- OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Opnd);
- // It may be the case that address mode optimization already creates
- // an OperandX8632Mem, so in that case it wouldn't need another level
- // of transformation.
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
+TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
+ bool DoLegalize) {
+ auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Opnd);
+ // It may be the case that address mode optimization already creates an
+ // Traits::X86OperandMem, so in that case it wouldn't need another level of
+ // transformation.
if (!Mem) {
Variable *Base = llvm::dyn_cast<Variable>(Opnd);
Constant *Offset = llvm::dyn_cast<Constant>(Opnd);
@@ -5188,11 +5152,11 @@ OperandX8632Mem *TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd,
assert(llvm::isa<ConstantInteger32>(Offset) ||
llvm::isa<ConstantRelocatable>(Offset));
}
- Mem = OperandX8632Mem::create(Func, Ty, Base, Offset);
+ Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
}
// Do legalization, which contains randomization/pooling
// or do randomization/pooling.
- return llvm::cast<OperandX8632Mem>(
+ return llvm::cast<typename Traits::X86OperandMem>(
DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
}
@@ -5218,68 +5182,8 @@ template <class Machine>
void TargetX86Base<Machine>::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const {
- // TODO(stichnot): Declaring Permutation this way loses type/size
- // information. Fix this in conjunction with the caller-side TODO.
- assert(Permutation.size() >= Traits::RegisterSet::Reg_NUM);
- // Expected upper bound on the number of registers in a single
- // equivalence class. For x86-32, this would comprise the 8 XMM
- // registers. This is for performance, not correctness.
- static const unsigned MaxEquivalenceClassSize = 8;
- typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList;
- typedef std::map<uint32_t, RegisterList> EquivalenceClassMap;
- EquivalenceClassMap EquivalenceClasses;
- SizeT NumShuffled = 0, NumPreserved = 0;
-
-// Build up the equivalence classes of registers by looking at the
-// register properties as well as whether the registers should be
-// explicitly excluded from shuffling.
-#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
- frameptr, isI8, isInt, isFP) \
- if (ExcludeRegisters[Traits::RegisterSet::val]) { \
- /* val stays the same in the resulting permutation. */ \
- Permutation[Traits::RegisterSet::val] = Traits::RegisterSet::val; \
- ++NumPreserved; \
- } else { \
- const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \
- (isInt << 3) | (isFP << 4); \
- /* val is assigned to an equivalence class based on its properties. */ \
- EquivalenceClasses[Index].push_back(Traits::RegisterSet::val); \
- }
- REGX8632_TABLE
-#undef X
-
- RandomNumberGeneratorWrapper RNG(Ctx->getRNG());
-
- // Shuffle the resulting equivalence classes.
- for (auto I : EquivalenceClasses) {
- const RegisterList &List = I.second;
- RegisterList Shuffled(List);
- RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG);
- for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) {
- Permutation[List[SI]] = Shuffled[SI];
- ++NumShuffled;
- }
- }
-
- assert(NumShuffled + NumPreserved == Traits::RegisterSet::Reg_NUM);
-
- if (Func->isVerbose(IceV_Random)) {
- OstreamLocker L(Func->getContext());
- Ostream &Str = Func->getContext()->getStrDump();
- Str << "Register equivalence classes:\n";
- for (auto I : EquivalenceClasses) {
- Str << "{";
- const RegisterList &List = I.second;
- bool First = true;
- for (int32_t Register : List) {
- if (!First)
- Str << " ";
- First = false;
- Str << getRegName(Register, IceType_i32);
- }
- Str << "}\n";
- }
- }
+ Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
+ ExcludeRegisters);
}
template <class Machine>
@@ -5350,8 +5254,8 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
uint32_t Cookie = Ctx->getRandomizationCookie();
_mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
- _lea(Reg,
- OperandX8632Mem::create(Func, IceType_i32, Reg, Offset, nullptr, 0));
+ _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset,
+ nullptr, 0));
// make sure liveness analysis won't kill this variable, otherwise a
// liveness
// assertion will be triggered.
@@ -5384,8 +5288,9 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
const bool SuppressMangling = true;
Constant *Symbol =
Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
- OperandX8632Mem *MemOperand =
- OperandX8632Mem::create(Func, Immediate->getType(), nullptr, Symbol);
+ typename Traits::X86OperandMem *MemOperand =
+ Traits::X86OperandMem::create(Func, Immediate->getType(), nullptr,
+ Symbol);
_mov(Reg, MemOperand);
return Reg;
}
@@ -5396,9 +5301,9 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
}
template <class Machine>
-OperandX8632Mem *
-TargetX86Base<Machine>::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
- int32_t RegNum) {
+typename TargetX86Base<Machine>::Traits::X86OperandMem *
+TargetX86Base<Machine>::randomizeOrPoolImmediate(
+ typename Traits::X86OperandMem *MemOperand, int32_t RegNum) {
assert(MemOperand);
if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
RandomizationPoolingPaused == true) {
@@ -5432,8 +5337,9 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
Constant *Mask2 =
Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
- OperandX8632Mem *TempMemOperand = OperandX8632Mem::create(
- Func, MemOperand->getType(), MemOperand->getBase(), Mask1);
+ typename Traits::X86OperandMem *TempMemOperand =
+ Traits::X86OperandMem::create(Func, MemOperand->getType(),
+ MemOperand->getBase(), Mask1);
// If we have already assigned a physical register, we must come from
// advancedPhiLowering()=>lowerAssign(). In this case we should reuse
// the assigned register as this assignment is that start of its use-def
@@ -5447,9 +5353,11 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
if (RegNum != Variable::NoRegister)
_set_dest_nonkillable();
- OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
- Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
- MemOperand->getShift(), MemOperand->getSegmentRegister());
+ typename Traits::X86OperandMem *NewMemOperand =
+ Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
+ Mask2, MemOperand->getIndex(),
+ MemOperand->getShift(),
+ MemOperand->getSegmentRegister());
// Label this memory operand as randomize, so we won't randomize it
// again in case we call legalize() mutiple times on this memory
@@ -5484,23 +5392,26 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(OperandX8632Mem *MemOperand,
bool SuppressMangling = true;
Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
SuppressMangling);
- OperandX8632Mem *SymbolOperand = OperandX8632Mem::create(
- Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
+ typename Traits::X86OperandMem *SymbolOperand =
+ Traits::X86OperandMem::create(
+ Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
_mov(RegTemp, SymbolOperand);
// If we have a base variable here, we should add the lea instruction
// to add the value of the base variable to RegTemp. If there is no
// base variable, we won't need this lea instruction.
if (MemOperand->getBase()) {
- OperandX8632Mem *CalculateOperand = OperandX8632Mem::create(
- Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
- RegTemp, 0, MemOperand->getSegmentRegister());
+ typename Traits::X86OperandMem *CalculateOperand =
+ Traits::X86OperandMem::create(
+ Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
+ RegTemp, 0, MemOperand->getSegmentRegister());
_lea(RegTemp, CalculateOperand);
_set_dest_nonkillable();
}
- OperandX8632Mem *NewMemOperand = OperandX8632Mem::create(
- Func, MemOperand->getType(), RegTemp, nullptr,
- MemOperand->getIndex(), MemOperand->getShift(),
- MemOperand->getSegmentRegister());
+ typename Traits::X86OperandMem *NewMemOperand =
+ Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
+ nullptr, MemOperand->getIndex(),
+ MemOperand->getShift(),
+ MemOperand->getSegmentRegister());
return NewMemOperand;
}
assert("Unsupported -randomize-pool-immediates option" && false);
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698