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

Unified Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1548363002: Subzero. Code organization. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years 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
Index: src/IceTargetLoweringX86BaseImpl.h
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index a169203e2e036a48eb8bea3245dfae8f91b4b007..04d9cdc00d08f884ecb4204804ed2cf07f8e024f 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -27,12 +27,13 @@
#include "IceOperand.h"
#include "IcePhiLoweringImpl.h"
#include "IceUtils.h"
+#include "IceInstX86Base.h"
Jim Stichnoth 2016/01/03 18:20:02 alphabetize includes
#include "llvm/Support/MathExtras.h"
#include <stack>
namespace Ice {
-namespace X86Internal {
+namespace X86NAMESPACE {
/// A helper class to ease the settings of RandomizationPoolingPause to disable
/// constant blinding or pooling for some translation phases.
@@ -50,7 +51,7 @@ private:
bool &Flag;
};
-template <class MachineTraits> class BoolFoldingEntry {
+template <typename Traits> class BoolFoldingEntry {
BoolFoldingEntry(const BoolFoldingEntry &) = delete;
public:
@@ -73,7 +74,7 @@ public:
uint32_t NumUses = 0;
};
-template <class MachineTraits> class BoolFolding {
+template <typename Traits> class BoolFolding {
public:
enum BoolFoldingProducerKind {
PK_None,
@@ -113,25 +114,25 @@ private:
}
void setInvalid(SizeT VarNum) { Producers[VarNum].Instr = nullptr; }
/// Producers maps Variable::Number to a BoolFoldingEntry.
- std::unordered_map<SizeT, BoolFoldingEntry<MachineTraits>> Producers;
+ std::unordered_map<SizeT, BoolFoldingEntry<Traits>> Producers;
};
-template <class MachineTraits>
-BoolFoldingEntry<MachineTraits>::BoolFoldingEntry(Inst *I)
- : Instr(I), IsComplex(BoolFolding<MachineTraits>::hasComplexLowering(I)) {}
+template <typename Traits>
+BoolFoldingEntry<Traits>::BoolFoldingEntry(Inst *I)
+ : Instr(I), IsComplex(BoolFolding<Traits>::hasComplexLowering(I)) {}
-template <class MachineTraits>
-typename BoolFolding<MachineTraits>::BoolFoldingProducerKind
-BoolFolding<MachineTraits>::getProducerKind(const Inst *Instr) {
+template <typename Traits>
+typename BoolFolding<Traits>::BoolFoldingProducerKind
+BoolFolding<Traits>::getProducerKind(const Inst *Instr) {
if (llvm::isa<InstIcmp>(Instr)) {
- if (MachineTraits::Is64Bit || Instr->getSrc(0)->getType() != IceType_i64)
+ if (Traits::Is64Bit || Instr->getSrc(0)->getType() != IceType_i64)
return PK_Icmp32;
return PK_Icmp64;
}
if (llvm::isa<InstFcmp>(Instr))
return PK_Fcmp;
if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) {
- if (MachineTraits::Is64Bit || Arith->getSrc(0)->getType() != IceType_i64) {
+ if (Traits::Is64Bit || Arith->getSrc(0)->getType() != IceType_i64) {
switch (Arith->getOp()) {
default:
return PK_None;
@@ -154,9 +155,9 @@ BoolFolding<MachineTraits>::getProducerKind(const Inst *Instr) {
return PK_None;
}
-template <class MachineTraits>
-typename BoolFolding<MachineTraits>::BoolFoldingConsumerKind
-BoolFolding<MachineTraits>::getConsumerKind(const Inst *Instr) {
+template <typename Traits>
+typename BoolFolding<Traits>::BoolFoldingConsumerKind
+BoolFolding<Traits>::getConsumerKind(const Inst *Instr) {
if (llvm::isa<InstBr>(Instr))
return CK_Br;
if (llvm::isa<InstSelect>(Instr))
@@ -181,23 +182,23 @@ BoolFolding<MachineTraits>::getConsumerKind(const Inst *Instr) {
/// 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) {
+template <typename Traits>
+bool BoolFolding<Traits>::hasComplexLowering(const Inst *Instr) {
switch (getProducerKind(Instr)) {
default:
return false;
case PK_Icmp64:
- return !MachineTraits::Is64Bit;
+ return !Traits::Is64Bit;
case PK_Fcmp:
- return MachineTraits::TableFcmp[llvm::cast<InstFcmp>(Instr)->getCondition()]
- .C2 != MachineTraits::Cond::Br_None;
+ return Traits::TableFcmp[llvm::cast<InstFcmp>(Instr)->getCondition()].C2 !=
+ Traits::Cond::Br_None;
}
}
-template <class MachineTraits>
-bool BoolFolding<MachineTraits>::isValidFolding(
- typename BoolFolding<MachineTraits>::BoolFoldingProducerKind ProducerKind,
- typename BoolFolding<MachineTraits>::BoolFoldingConsumerKind ConsumerKind) {
+template <typename Traits>
+bool BoolFolding<Traits>::isValidFolding(
+ typename BoolFolding<Traits>::BoolFoldingProducerKind ProducerKind,
+ typename BoolFolding<Traits>::BoolFoldingConsumerKind ConsumerKind) {
switch (ProducerKind) {
default:
return false;
@@ -210,8 +211,7 @@ bool BoolFolding<MachineTraits>::isValidFolding(
}
}
-template <class MachineTraits>
-void BoolFolding<MachineTraits>::init(CfgNode *Node) {
+template <typename Traits> void BoolFolding<Traits>::init(CfgNode *Node) {
Producers.clear();
for (Inst &Instr : Node->getInsts()) {
// Check whether Instr is a valid producer.
@@ -220,7 +220,7 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) {
&& Var // only instructions with an actual dest var
&& Var->getType() == IceType_i1 // only bool-type dest vars
&& getProducerKind(&Instr) != PK_None) { // white-listed instructions
- Producers[Var->getIndex()] = BoolFoldingEntry<MachineTraits>(&Instr);
+ Producers[Var->getIndex()] = BoolFoldingEntry<Traits>(&Instr);
}
// Check each src variable against the map.
FOREACH_VAR_IN_INST(Var, Instr) {
@@ -233,14 +233,14 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) {
continue;
}
// Consumer instructions must be white-listed
- typename BoolFolding<MachineTraits>::BoolFoldingConsumerKind
- ConsumerKind = getConsumerKind(&Instr);
+ typename BoolFolding<Traits>::BoolFoldingConsumerKind ConsumerKind =
+ getConsumerKind(&Instr);
if (ConsumerKind == CK_None) {
setInvalid(VarNum);
continue;
}
- typename BoolFolding<MachineTraits>::BoolFoldingProducerKind
- ProducerKind = getProducerKind(Producers[VarNum].Instr);
+ typename BoolFolding<Traits>::BoolFoldingProducerKind ProducerKind =
+ getProducerKind(Producers[VarNum].Instr);
if (!isValidFolding(ProducerKind, ConsumerKind)) {
setInvalid(VarNum);
continue;
@@ -273,9 +273,8 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) {
}
}
-template <class MachineTraits>
-const Inst *
-BoolFolding<MachineTraits>::getProducerFor(const Operand *Opnd) const {
+template <typename Traits>
+const Inst *BoolFolding<Traits>::getProducerFor(const Operand *Opnd) const {
auto *Var = llvm::dyn_cast<const Variable>(Opnd);
if (Var == nullptr)
return nullptr;
@@ -286,8 +285,8 @@ BoolFolding<MachineTraits>::getProducerFor(const Operand *Opnd) const {
return Element->second.Instr;
}
-template <class MachineTraits>
-void BoolFolding<MachineTraits>::dump(const Cfg *Func) const {
+template <typename Traits>
+void BoolFolding<Traits>::dump(const Cfg *Func) const {
if (!BuildDefs::dump() || !Func->isVerbose(IceV_Folding))
return;
OstreamLocker L(Func->getContext());
@@ -301,14 +300,14 @@ void BoolFolding<MachineTraits>::dump(const Cfg *Func) const {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::initNodeForLowering(CfgNode *Node) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::initNodeForLowering(CfgNode *Node) {
FoldingInfo.init(Node);
FoldingInfo.dump(Func);
}
-template <class Machine>
-TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
+template <typename TraitsType>
+TargetX86Base<TraitsType>::TargetX86Base(Cfg *Func)
: TargetLowering(Func) {
static_assert(
(Traits::InstructionSet::End - Traits::InstructionSet::Begin) ==
@@ -317,18 +316,18 @@ TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
"Traits::InstructionSet range different from TargetInstructionSet");
if (Func->getContext()->getFlags().getTargetInstructionSet() !=
TargetInstructionSet::BaseInstructionSet) {
- InstructionSet = static_cast<typename Traits::InstructionSet>(
+ InstructionSet = static_cast<InstructionSetEnum>(
(Func->getContext()->getFlags().getTargetInstructionSet() -
TargetInstructionSet::X86InstructionSet_Begin) +
Traits::InstructionSet::Begin);
}
}
-template <class Machine> void TargetX86Base<Machine>::staticInit() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::staticInit() {
Traits::initRegisterSet(&TypeToRegisterSet, &RegisterAliases, &ScratchRegs);
}
-template <class Machine> void TargetX86Base<Machine>::translateO2() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::translateO2() {
TimerMarker T(TimerStack::TT_O2, Func);
genTargetHelperCalls();
@@ -454,7 +453,7 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
Func->markNodesForSandboxing();
}
-template <class Machine> void TargetX86Base<Machine>::translateOm1() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::translateOm1() {
TimerMarker T(TimerStack::TT_Om1, Func);
genTargetHelperCalls();
@@ -531,14 +530,16 @@ inline bool canRMW(const InstArithmetic *Arith) {
}
}
-template <class Machine>
+template <typename TraitsType>
bool isSameMemAddressOperand(const Operand *A, const Operand *B) {
if (A == B)
return true;
- if (auto *MemA = llvm::dyn_cast<
- typename TargetX86Base<Machine>::Traits::X86OperandMem>(A)) {
- if (auto *MemB = llvm::dyn_cast<
- typename TargetX86Base<Machine>::Traits::X86OperandMem>(B)) {
+ if (auto *MemA =
+ llvm::dyn_cast<typename TargetX86Base<TraitsType>::X86OperandMem>(
+ A)) {
+ if (auto *MemB =
+ llvm::dyn_cast<typename TargetX86Base<TraitsType>::X86OperandMem>(
+ B)) {
return MemA->getBase() == MemB->getBase() &&
MemA->getOffset() == MemB->getOffset() &&
MemA->getIndex() == MemB->getIndex() &&
@@ -549,7 +550,7 @@ bool isSameMemAddressOperand(const Operand *A, const Operand *B) {
return false;
}
-template <class Machine> void TargetX86Base<Machine>::findRMW() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::findRMW() {
Func->dump("Before RMW");
if (Func->isVerbose(IceV_RMW))
Func->getContext()->lockStr();
@@ -603,8 +604,8 @@ template <class Machine> void TargetX86Base<Machine>::findRMW() {
// 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<Machine>(Load->getSourceAddress(),
- Store->getAddr()))
+ if (!isSameMemAddressOperand<TraitsType>(Load->getSourceAddress(),
+ Store->getAddr()))
continue;
Operand *ArithSrcFromLoad = Arith->getSrc(0);
Operand *ArithSrcOther = Arith->getSrc(1);
@@ -632,8 +633,8 @@ template <class Machine> void TargetX86Base<Machine>::findRMW() {
Store->setRmwBeacon(Beacon);
auto *BeaconDef = InstFakeDef::create(Func, Beacon);
Node->getInsts().insert(I3, BeaconDef);
- auto *RMW = Traits::Insts::FakeRMW::create(
- Func, ArithSrcOther, Store->getAddr(), Beacon, Arith->getOp());
+ auto *RMW = InstX86FakeRMW::create(Func, ArithSrcOther, Store->getAddr(),
+ Beacon, Arith->getOp());
Node->getInsts().insert(I3, RMW);
}
}
@@ -666,7 +667,7 @@ inline bool canFoldLoadIntoBinaryInst(Operand *LoadSrc, Variable *LoadDest,
return false;
}
-template <class Machine> void TargetX86Base<Machine>::doLoadOpt() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::doLoadOpt() {
for (CfgNode *Node : Func->getNodes()) {
Context.init(Node);
while (!Context.atEnd()) {
@@ -755,16 +756,17 @@ template <class Machine> void TargetX86Base<Machine>::doLoadOpt() {
Func->dump("After load optimization");
}
-template <class Machine>
-bool TargetX86Base<Machine>::doBranchOpt(Inst *I, const CfgNode *NextNode) {
- if (auto *Br = llvm::dyn_cast<typename Traits::Insts::Br>(I)) {
+template <typename TraitsType>
+bool TargetX86Base<TraitsType>::doBranchOpt(Inst *I, const CfgNode *NextNode) {
+ if (auto *Br = llvm::dyn_cast<InstX86Br>(I)) {
return Br->optimizeBranch(NextNode);
}
return false;
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::getPhysicalRegister(SizeT RegNum,
+ Type Ty) {
if (Ty == IceType_void)
Ty = IceType_i32;
if (PhysicalRegisters[Ty].empty())
@@ -786,13 +788,13 @@ Variable *TargetX86Base<Machine>::getPhysicalRegister(SizeT RegNum, Type Ty) {
return Reg;
}
-template <class Machine>
-IceString TargetX86Base<Machine>::getRegName(SizeT RegNum, Type Ty) const {
+template <typename TraitsType>
+IceString TargetX86Base<TraitsType>::getRegName(SizeT RegNum, Type Ty) const {
return Traits::getRegName(Traits::getGprForType(Ty, RegNum));
}
-template <class Machine>
-void TargetX86Base<Machine>::emitVariable(const Variable *Var) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emitVariable(const Variable *Var) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
@@ -823,9 +825,9 @@ void TargetX86Base<Machine>::emitVariable(const Variable *Var) const {
Str << "(%" << getRegName(BaseRegNum, FrameSPTy) << ")";
}
-template <class Machine>
-typename TargetX86Base<Machine>::Traits::Address
-TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const {
+template <typename TraitsType>
+typename TargetX86Base<TraitsType>::X86Address
+TargetX86Base<TraitsType>::stackVarToAsmOperand(const Variable *Var) const {
if (Var->hasReg())
llvm_unreachable("Stack Variable has a register assigned");
if (Var->mustHaveReg()) {
@@ -835,8 +837,8 @@ TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const {
int32_t BaseRegNum = Var->getBaseRegNum();
if (Var->getBaseRegNum() == Variable::NoRegister)
BaseRegNum = getFrameOrStackReg();
- return typename Traits::Address(Traits::getEncodedGPR(BaseRegNum), Offset,
- AssemblerFixup::NoFixup);
+ return X86Address(Traits::getEncodedGPR(BaseRegNum), Offset,
+ AssemblerFixup::NoFixup);
}
/// Helper function for addProlog().
@@ -847,12 +849,10 @@ TargetX86Base<Machine>::stackVarToAsmOperand(const Variable *Var) const {
/// recursively on the components, taking care to handle Lo first because of the
/// little-endian architecture. Lastly, this function generates an instruction
/// to copy Arg into its assigned register if applicable.
-template <class Machine>
-void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
- Variable *FramePtr,
- size_t BasicFrameOffset,
- size_t StackAdjBytes,
- size_t &InArgsSizeBytes) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::finishArgumentLowering(
+ Variable *Arg, Variable *FramePtr, size_t BasicFrameOffset,
+ size_t StackAdjBytes, size_t &InArgsSizeBytes) {
if (!Traits::Is64Bit) {
if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
Variable *Lo = Arg64On32->getLo();
@@ -872,7 +872,7 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
if (Arg->hasReg()) {
assert(Ty != IceType_i64 || Traits::Is64Bit);
- auto *Mem = Traits::X86OperandMem::create(
+ auto *Mem = X86OperandMem::create(
Func, Ty, FramePtr,
Ctx->getConstantInt32(Arg->getStackOffset() + StackAdjBytes));
if (isVectorType(Arg->getType())) {
@@ -880,21 +880,21 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
} else {
_mov(Arg, Mem);
}
- // This argument-copying instruction uses an explicit Traits::X86OperandMem
+ // This argument-copying instruction uses an explicit X86OperandMem
// operand instead of a Variable, so its fill-from-stack operation has to
// be tracked separately for statistics.
Ctx->statsUpdateFills();
}
}
-template <class Machine> Type TargetX86Base<Machine>::stackSlotType() {
+template <typename TraitsType> Type TargetX86Base<TraitsType>::stackSlotType() {
return Traits::WordType;
}
-template <class Machine>
+template <typename TraitsType>
template <typename T>
typename std::enable_if<!T::Is64Bit, Operand>::type *
-TargetX86Base<Machine>::loOperand(Operand *Operand) {
+TargetX86Base<TraitsType>::loOperand(Operand *Operand) {
assert(Operand->getType() == IceType_i64 ||
Operand->getType() == IceType_f64);
if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
@@ -907,8 +907,8 @@ TargetX86Base<Machine>::loOperand(Operand *Operand) {
// Check if we need to blind/pool the constant.
return legalize(ConstInt);
}
- if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
- auto *MemOperand = Traits::X86OperandMem::create(
+ if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Operand)) {
+ auto *MemOperand = 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
@@ -920,10 +920,10 @@ TargetX86Base<Machine>::loOperand(Operand *Operand) {
return nullptr;
}
-template <class Machine>
+template <typename TraitsType>
template <typename T>
typename std::enable_if<!T::Is64Bit, Operand>::type *
-TargetX86Base<Machine>::hiOperand(Operand *Operand) {
+TargetX86Base<TraitsType>::hiOperand(Operand *Operand) {
assert(Operand->getType() == IceType_i64 ||
Operand->getType() == IceType_f64);
if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
@@ -936,7 +936,7 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
// Check if we need to blind/pool the constant.
return legalize(ConstInt);
}
- if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Operand)) {
+ if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Operand)) {
Constant *Offset = Mem->getOffset();
if (Offset == nullptr) {
Offset = Ctx->getConstantInt32(4);
@@ -948,7 +948,7 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
Ctx->getConstantSym(4 + SymOffset->getOffset(), SymOffset->getName(),
SymOffset->getSuppressMangling());
}
- auto *MemOperand = Traits::X86OperandMem::create(
+ auto *MemOperand = 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
@@ -960,15 +960,15 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
return nullptr;
}
-template <class Machine>
+template <typename TraitsType>
llvm::SmallBitVector
-TargetX86Base<Machine>::getRegisterSet(RegSetMask Include,
- RegSetMask Exclude) const {
+TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include,
+ RegSetMask Exclude) const {
return Traits::getRegisterSet(Include, Exclude);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Inst) {
// Conservatively require the stack to be aligned. Some stack adjustment
// operations implemented below assume that the stack is aligned before the
// alloca. All the alloca code ensures that the stack alignment is preserved
@@ -1034,10 +1034,8 @@ void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
uint32_t OutArgsSize = maxOutArgsSizeBytes();
if (OutArgsSize > 0) {
Variable *T = makeReg(IceType_i32);
- typename Traits::X86OperandMem *CalculateOperand =
- Traits::X86OperandMem::create(
- Func, IceType_i32, esp,
- Ctx->getConstantInt(IceType_i32, OutArgsSize));
+ auto *CalculateOperand = X86OperandMem::create(
+ Func, IceType_i32, esp, Ctx->getConstantInt(IceType_i32, OutArgsSize));
_lea(T, CalculateOperand);
_mov(Dest, T);
} else {
@@ -1050,9 +1048,9 @@ void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
/// by 3, 5, or 9, and the lsh instruction can be used to multiply by powers of
/// 2. These can be combined such that e.g. multiplying by 100 can be done as 2
/// lea-based multiplies by 5, combined with left-shifting by 2.
-template <class Machine>
-bool TargetX86Base<Machine>::optimizeScalarMul(Variable *Dest, Operand *Src0,
- int32_t Src1) {
+template <typename TraitsType>
+bool TargetX86Base<TraitsType>::optimizeScalarMul(Variable *Dest, Operand *Src0,
+ int32_t Src1) {
// Disable this optimization for Om1 and O0, just to keep things simple
// there.
if (Ctx->getFlags().getOptLevel() < Opt_1)
@@ -1119,18 +1117,15 @@ bool TargetX86Base<Machine>::optimizeScalarMul(Variable *Dest, Operand *Src0,
Constant *Zero = Ctx->getConstantZero(IceType_i32);
for (uint32_t i = 0; i < Count9; ++i) {
constexpr uint16_t Shift = 3; // log2(9-1)
- _lea(T,
- Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T, X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
for (uint32_t i = 0; i < Count5; ++i) {
constexpr uint16_t Shift = 2; // log2(5-1)
- _lea(T,
- Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T, X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
for (uint32_t i = 0; i < Count3; ++i) {
constexpr uint16_t Shift = 1; // log2(3-1)
- _lea(T,
- Traits::X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
+ _lea(T, X86OperandMem::create(Func, IceType_void, T, Zero, T, Shift));
}
if (Count2) {
_shl(T, Ctx->getConstantInt(Ty, Count2));
@@ -1141,11 +1136,11 @@ bool TargetX86Base<Machine>::optimizeScalarMul(Variable *Dest, Operand *Src0,
return true;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerShift64(InstArithmetic::OpKind Op,
- Operand *Src0Lo, Operand *Src0Hi,
- Operand *Src1Lo, Variable *DestLo,
- Variable *DestHi) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerShift64(InstArithmetic::OpKind Op,
+ Operand *Src0Lo, Operand *Src0Hi,
+ Operand *Src1Lo, Variable *DestLo,
+ Variable *DestHi) {
// TODO: Refactor the similarities between Shl, Lshr, and Ashr.
Variable *T_1 = nullptr, *T_2 = nullptr, *T_3 = nullptr;
Constant *Zero = Ctx->getConstantZero(IceType_i32);
@@ -1274,8 +1269,7 @@ void TargetX86Base<Machine>::lowerShift64(InstArithmetic::OpKind Op,
} else {
// NON-CONSTANT CASES.
Constant *BitTest = Ctx->getConstantInt32(0x20);
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
// COMMON PREFIX OF: a=b SHIFT_OP c ==>
// t1:ecx = c.lo & 0xff
// t2 = b.lo
@@ -1355,8 +1349,8 @@ void TargetX86Base<Machine>::lowerShift64(InstArithmetic::OpKind Op,
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Inst) {
Variable *Dest = Inst->getDest();
if (Dest->isRematerializable()) {
Context.insert<InstFakeDef>(Dest);
@@ -1508,7 +1502,7 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
if (isVectorType(Ty)) {
// TODO: Trap on integer divide and integer modulo by zero. See:
// https://code.google.com/p/nativeclient/issues/detail?id=3899
- if (llvm::isa<typename Traits::X86OperandMem>(Src1))
+ if (llvm::isa<X86OperandMem>(Src1))
Src1 = legalizeToReg(Src1);
switch (Inst->getOp()) {
case InstArithmetic::_num:
@@ -1927,8 +1921,8 @@ void TargetX86Base<Machine>::lowerArithmetic(const InstArithmetic *Inst) {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerAssign(const InstAssign *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerAssign(const InstAssign *Inst) {
Variable *Dest = Inst->getDest();
if (Dest->isRematerializable()) {
Context.insert<InstFakeDef>(Dest);
@@ -1939,8 +1933,8 @@ void TargetX86Base<Machine>::lowerAssign(const InstAssign *Inst) {
lowerMove(Dest, Src, false);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerBr(const InstBr *Br) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerBr(const InstBr *Br) {
if (Br->isUnconditional()) {
_br(Br->getTargetUnconditional());
return;
@@ -1974,8 +1968,8 @@ void TargetX86Base<Machine>::lowerBr(const InstBr *Br) {
_br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse());
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerCast(const InstCast *Inst) {
// a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap)
InstCast::OpKind CastKind = Inst->getCastKind();
Variable *Dest = Inst->getDest();
@@ -2153,7 +2147,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
assert(DestTy == IceType_v4i32 &&
Inst->getSrc(0)->getType() == IceType_v4f32);
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
- if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
+ if (llvm::isa<X86OperandMem>(Src0RM))
Src0RM = legalizeToReg(Src0RM);
Variable *T = makeReg(DestTy);
_cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
@@ -2219,7 +2213,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
assert(DestTy == IceType_v4f32 &&
Inst->getSrc(0)->getType() == IceType_v4i32);
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
- if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
+ if (llvm::isa<X86OperandMem>(Src0RM))
Src0RM = legalizeToReg(Src0RM);
Variable *T = makeReg(DestTy);
_cvt(T, Src0RM, Traits::Insts::Cvt::Dq2ps);
@@ -2304,8 +2298,7 @@ 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.
- typename Traits::SpillVariable *SpillVar =
- Func->makeVariable<typename Traits::SpillVariable>(SrcType);
+ SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(SrcType);
SpillVar->setLinkedTo(Dest);
Variable *Spill = SpillVar;
Spill->setMustNotHaveReg();
@@ -2330,8 +2323,8 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// a_hi.i32 = t_hi.i32
Operand *SpillLo, *SpillHi;
if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
- typename Traits::SpillVariable *SpillVar =
- Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
+ SpillVariable *SpillVar =
+ Func->makeVariable<SpillVariable>(IceType_f64);
SpillVar->setLinkedTo(Src0Var);
Variable *Spill = SpillVar;
Spill->setMustNotHaveReg();
@@ -2365,7 +2358,7 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
_mov(Dest, T);
} else {
Src0 = legalize(Src0);
- if (llvm::isa<typename Traits::X86OperandMem>(Src0)) {
+ if (llvm::isa<X86OperandMem>(Src0)) {
Variable *T = Func->makeVariable(DestTy);
_movq(T, Src0);
_movq(Dest, T);
@@ -2378,8 +2371,8 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
// t_hi.i32 = b_hi.i32
// hi(s.f64) = t_hi.i32
// a.f64 = s.f64
- typename Traits::SpillVariable *SpillVar =
- Func->makeVariable<typename Traits::SpillVariable>(IceType_f64);
+ SpillVariable *SpillVar =
+ Func->makeVariable<SpillVariable>(IceType_f64);
SpillVar->setLinkedTo(Dest);
Variable *Spill = SpillVar;
Spill->setMustNotHaveReg();
@@ -2418,8 +2411,8 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerExtractElement(
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerExtractElement(
const InstExtractElement *Inst) {
Operand *SourceVectNotLegalized = Inst->getSrc(0);
ConstantInteger32 *ElementIndex =
@@ -2481,7 +2474,7 @@ void TargetX86Base<Machine>::lowerExtractElement(
// Compute the location of the element in memory.
unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
- typename Traits::X86OperandMem *Loc =
+ X86OperandMem *Loc =
getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
_mov(ExtractedElementR, Loc);
}
@@ -2500,8 +2493,8 @@ void TargetX86Base<Machine>::lowerExtractElement(
_mov(Dest, ExtractedElementR);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Fcmp) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerFcmp(const InstFcmp *Fcmp) {
Variable *Dest = Fcmp->getDest();
if (isVectorType(Dest->getType())) {
@@ -2512,9 +2505,9 @@ void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Fcmp) {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerFcmpAndConsumer(const InstFcmp *Fcmp,
- const Inst *Consumer) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerFcmpAndConsumer(const InstFcmp *Fcmp,
+ const Inst *Consumer) {
Operand *Src0 = Fcmp->getSrc(0);
Operand *Src1 = Fcmp->getSrc(1);
Variable *Dest = Fcmp->getDest();
@@ -2566,8 +2559,7 @@ void TargetX86Base<Machine>::lowerFcmpAndConsumer(const InstFcmp *Fcmp,
Constant *Default = Ctx->getConstantInt(Dest->getType(), IntDefault);
_mov(Dest, Default);
if (HasC1) {
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
_br(Traits::TableFcmp[Index].C1, Label);
if (HasC2) {
_br(Traits::TableFcmp[Index].C2, Label);
@@ -2602,8 +2594,7 @@ void TargetX86Base<Machine>::lowerFcmpAndConsumer(const InstFcmp *Fcmp,
std::swap(SrcT, SrcF);
lowerMove(SelectDest, SrcF, false);
if (HasC1) {
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
_br(Traits::TableFcmp[Index].C1, Label);
if (HasC2) {
_br(Traits::TableFcmp[Index].C2, Label);
@@ -2617,8 +2608,8 @@ void TargetX86Base<Machine>::lowerFcmpAndConsumer(const InstFcmp *Fcmp,
llvm::report_fatal_error("Unexpected consumer type");
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerFcmpVector(const InstFcmp *Fcmp) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerFcmpVector(const InstFcmp *Fcmp) {
Operand *Src0 = Fcmp->getSrc(0);
Operand *Src1 = Fcmp->getSrc(1);
Variable *Dest = Fcmp->getDest();
@@ -2643,13 +2634,12 @@ void TargetX86Base<Machine>::lowerFcmpVector(const InstFcmp *Fcmp) {
} else {
Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
- if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
+ if (llvm::isa<X86OperandMem>(Src1RM))
Src1RM = legalizeToReg(Src1RM);
switch (Condition) {
default: {
- typename Traits::Cond::CmppsCond Predicate =
- Traits::TableFcmp[Index].Predicate;
+ CmppsCond Predicate = Traits::TableFcmp[Index].Predicate;
assert(Predicate != Traits::Cond::Cmpps_Invalid);
T = makeReg(Src0RM->getType());
_movp(T, Src0RM);
@@ -2691,9 +2681,9 @@ inline bool isZero(const Operand *Opnd) {
return false;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerIcmpAndConsumer(const InstIcmp *Icmp,
- const Inst *Consumer) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerIcmpAndConsumer(const InstIcmp *Icmp,
+ const Inst *Consumer) {
Operand *Src0 = legalize(Icmp->getSrc(0));
Operand *Src1 = legalize(Icmp->getSrc(1));
Variable *Dest = Icmp->getDest();
@@ -2725,8 +2715,8 @@ void TargetX86Base<Machine>::lowerIcmpAndConsumer(const InstIcmp *Icmp,
Consumer);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerIcmpVector(const InstIcmp *Icmp) {
Operand *Src0 = legalize(Icmp->getSrc(0));
Operand *Src1 = legalize(Icmp->getSrc(1));
Variable *Dest = Icmp->getDest();
@@ -2788,13 +2778,13 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
llvm_unreachable("unexpected condition");
break;
case InstIcmp::Eq: {
- if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
+ if (llvm::isa<X86OperandMem>(Src1RM))
Src1RM = legalizeToReg(Src1RM);
_movp(T, Src0RM);
_pcmpeq(T, Src1RM);
} break;
case InstIcmp::Ne: {
- if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
+ if (llvm::isa<X86OperandMem>(Src1RM))
Src1RM = legalizeToReg(Src1RM);
_movp(T, Src0RM);
_pcmpeq(T, Src1RM);
@@ -2803,7 +2793,7 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
} break;
case InstIcmp::Ugt:
case InstIcmp::Sgt: {
- if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
+ if (llvm::isa<X86OperandMem>(Src1RM))
Src1RM = legalizeToReg(Src1RM);
_movp(T, Src0RM);
_pcmpgt(T, Src1RM);
@@ -2811,7 +2801,7 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
case InstIcmp::Uge:
case InstIcmp::Sge: {
// !(Src1RM > Src0RM)
- if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
+ if (llvm::isa<X86OperandMem>(Src0RM))
Src0RM = legalizeToReg(Src0RM);
_movp(T, Src1RM);
_pcmpgt(T, Src0RM);
@@ -2820,7 +2810,7 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
} break;
case InstIcmp::Ult:
case InstIcmp::Slt: {
- if (llvm::isa<typename Traits::X86OperandMem>(Src0RM))
+ if (llvm::isa<X86OperandMem>(Src0RM))
Src0RM = legalizeToReg(Src0RM);
_movp(T, Src1RM);
_pcmpgt(T, Src0RM);
@@ -2828,7 +2818,7 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
case InstIcmp::Ule:
case InstIcmp::Sle: {
// !(Src0RM > Src1RM)
- if (llvm::isa<typename Traits::X86OperandMem>(Src1RM))
+ if (llvm::isa<X86OperandMem>(Src1RM))
Src1RM = legalizeToReg(Src1RM);
_movp(T, Src0RM);
_pcmpgt(T, Src1RM);
@@ -2841,11 +2831,11 @@ void TargetX86Base<Machine>::lowerIcmpVector(const InstIcmp *Icmp) {
eliminateNextVectorSextInstruction(Dest);
}
-template <typename Machine>
+template <typename TraitsType>
template <typename T>
typename std::enable_if<!T::Is64Bit, void>::type
-TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
- const Inst *Consumer) {
+TargetX86Base<TraitsType>::lowerIcmp64(const InstIcmp *Icmp,
+ const Inst *Consumer) {
// a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1:
Operand *Src0 = legalize(Icmp->getSrc(0));
Operand *Src1 = legalize(Icmp->getSrc(1));
@@ -2940,10 +2930,8 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
if (Consumer == nullptr) {
Constant *Zero = Ctx->getConstantInt(Dest->getType(), 0);
Constant *One = Ctx->getConstantInt(Dest->getType(), 1);
- typename Traits::Insts::Label *LabelFalse =
- Traits::Insts::Label::create(Func, this);
- typename Traits::Insts::Label *LabelTrue =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *LabelFalse = InstX86Label::create(Func, this);
+ InstX86Label *LabelTrue = InstX86Label::create(Func, this);
_mov(Dest, One);
_cmp(Src0HiRM, Src1HiRI);
if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None)
@@ -2972,10 +2960,8 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
Operand *SrcT = Select->getTrueOperand();
Operand *SrcF = Select->getFalseOperand();
Variable *SelectDest = Select->getDest();
- typename Traits::Insts::Label *LabelFalse =
- Traits::Insts::Label::create(Func, this);
- typename Traits::Insts::Label *LabelTrue =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *LabelFalse = InstX86Label::create(Func, this);
+ InstX86Label *LabelTrue = InstX86Label::create(Func, this);
lowerMove(SelectDest, SrcT, false);
_cmp(Src0HiRM, Src1HiRI);
if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None)
@@ -2993,10 +2979,10 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp,
llvm::report_fatal_error("Unexpected consumer type");
}
-template <class Machine>
-void TargetX86Base<Machine>::setccOrConsumer(
- typename Traits::Cond::BrCond Condition, Variable *Dest,
- const Inst *Consumer) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::setccOrConsumer(BrCond Condition,
+ Variable *Dest,
+ const Inst *Consumer) {
if (Consumer == nullptr) {
_setcc(Dest, Condition);
return;
@@ -3015,9 +3001,9 @@ void TargetX86Base<Machine>::setccOrConsumer(
llvm::report_fatal_error("Unexpected consumer type");
}
-template <class Machine>
-void TargetX86Base<Machine>::movOrConsumer(bool IcmpResult, Variable *Dest,
- const Inst *Consumer) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::movOrConsumer(bool IcmpResult, Variable *Dest,
+ const Inst *Consumer) {
if (Consumer == nullptr) {
_mov(Dest, Ctx->getConstantInt(Dest->getType(), (IcmpResult ? 1 : 0)));
return;
@@ -3045,9 +3031,9 @@ void TargetX86Base<Machine>::movOrConsumer(bool IcmpResult, Variable *Dest,
llvm::report_fatal_error("Unexpected consumer type");
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerArithAndConsumer(const InstArithmetic *Arith,
- const Inst *Consumer) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerArithAndConsumer(
+ const InstArithmetic *Arith, const Inst *Consumer) {
Variable *T = nullptr;
Operand *Src0 = legalize(Arith->getSrc(0));
Operand *Src1 = legalize(Arith->getSrc(1));
@@ -3084,8 +3070,9 @@ void TargetX86Base<Machine>::lowerArithAndConsumer(const InstArithmetic *Arith,
llvm::report_fatal_error("Unexpected consumer type");
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerInsertElement(
+ const InstInsertElement *Inst) {
Operand *SourceVectNotLegalized = Inst->getSrc(0);
Operand *ElementToInsertNotLegalized = Inst->getSrc(1);
ConstantInteger32 *ElementIndex =
@@ -3123,7 +3110,8 @@ void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) {
} else {
// For the pinsrb and pinsrw instructions, when the source operand is a
// register, it must be a full r32 register like eax, and not ax/al/ah.
- // For filetype=asm, InstX86Pinsr<Machine>::emit() compensates for the use
+ // For filetype=asm, InstX86Pinsr<TraitsType>::emit() compensates for
+ // the use
// of r16 and r8 by converting them through getBaseReg(), while emitIAS()
// validates that the original and base register encodings are the same.
if (ElementRM->getType() == IceType_i8 &&
@@ -3208,7 +3196,7 @@ void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) {
// Compute the location of the position to insert in memory.
unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
- typename Traits::X86OperandMem *Loc =
+ X86OperandMem *Loc =
getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
_store(legalizeToReg(ElementToInsertNotLegalized), Loc);
@@ -3218,8 +3206,8 @@ void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerIntrinsicCall(
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerIntrinsicCall(
const InstIntrinsicCall *Instr) {
switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
case Intrinsics::AtomicCmpxchg: {
@@ -3299,8 +3287,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
// anyway, since this is x86-32 and integer arithmetic only happens on
// 32-bit quantities.
Variable *T = makeReg(IceType_f64);
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Instr->getArg(0), IceType_f64);
+ 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.
auto *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
@@ -3350,8 +3337,7 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
auto *Cast = InstCast::create(Func, InstCast::Bitcast, T, Value);
lowerCast(Cast);
// Then store XMM w/ a movq.
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, IceType_f64);
+ X86OperandMem *Addr = formMemoryOperand(Ptr, IceType_f64);
_storeq(T, Addr);
_mfence();
return;
@@ -3495,7 +3481,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<typename Traits::X86OperandMem>(Src))
+ if (llvm::isa<X86OperandMem>(Src))
Src = legalizeToReg(Src);
} else {
Src = legalizeToReg(Src);
@@ -3528,7 +3514,8 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
}
case Intrinsics::NaClReadTP: {
if (Ctx->getFlags().getUseSandboxing()) {
- Operand *Src = dispatchToConcrete(&Machine::createNaClReadTPSrcOperand);
+ Operand *Src =
+ dispatchToConcrete(&ConcreteTarget::createNaClReadTPSrcOperand);
Variable *Dest = Instr->getDest();
Variable *T = nullptr;
_mov(T, Src);
@@ -3578,10 +3565,11 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
return;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
- Operand *Ptr, Operand *Expected,
- Operand *Desired) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerAtomicCmpxchg(Variable *DestPrev,
+ Operand *Ptr,
+ Operand *Expected,
+ Operand *Desired) {
Type Ty = Expected->getType();
if (!Traits::Is64Bit && Ty == IceType_i64) {
// Reserve the pre-colored registers first, before adding any more
@@ -3594,7 +3582,7 @@ void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
_mov(T_edx, hiOperand(Expected));
_mov(T_ebx, loOperand(Desired));
_mov(T_ecx, hiOperand(Desired));
- typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
constexpr bool Locked = true;
_cmpxchg8b(Addr, T_edx, T_eax, T_ecx, T_ebx, Locked);
auto *DestLo = llvm::cast<Variable>(loOperand(DestPrev));
@@ -3622,18 +3610,18 @@ void TargetX86Base<Machine>::lowerAtomicCmpxchg(Variable *DestPrev,
}
Variable *T_eax = makeReg(Ty, Eax);
_mov(T_eax, Expected);
- typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
Variable *DesiredReg = legalizeToReg(Desired);
constexpr bool Locked = true;
_cmpxchg(Addr, T_eax, DesiredReg, Locked);
_mov(DestPrev, T_eax);
}
-template <class Machine>
-bool TargetX86Base<Machine>::tryOptimizedCmpxchgCmpBr(Variable *Dest,
- Operand *PtrToMem,
- Operand *Expected,
- Operand *Desired) {
+template <typename TraitsType>
+bool TargetX86Base<TraitsType>::tryOptimizedCmpxchgCmpBr(Variable *Dest,
+ Operand *PtrToMem,
+ Operand *Expected,
+ Operand *Desired) {
if (Ctx->getFlags().getOptLevel() == Opt_m1)
return false;
// Peek ahead a few instructions and see how Dest is used.
@@ -3705,9 +3693,10 @@ bool TargetX86Base<Machine>::tryOptimizedCmpxchgCmpBr(Variable *Dest,
return false;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
- Operand *Ptr, Operand *Val) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerAtomicRMW(Variable *Dest,
+ uint32_t Operation, Operand *Ptr,
+ Operand *Val) {
bool NeedsCmpxchg = false;
LowerBinOp Op_Lo = nullptr;
LowerBinOp Op_Hi = nullptr;
@@ -3720,12 +3709,11 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
// All the fall-through paths must set this to true, but use this
// for asserting.
NeedsCmpxchg = true;
- Op_Lo = &TargetX86Base<Machine>::_add;
- Op_Hi = &TargetX86Base<Machine>::_adc;
+ Op_Lo = &TargetX86Base<TraitsType>::_add;
+ Op_Hi = &TargetX86Base<TraitsType>::_adc;
break;
}
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, Dest->getType());
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Dest->getType());
constexpr bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
@@ -3736,12 +3724,11 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
case Intrinsics::AtomicSub: {
if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
NeedsCmpxchg = true;
- Op_Lo = &TargetX86Base<Machine>::_sub;
- Op_Hi = &TargetX86Base<Machine>::_sbb;
+ Op_Lo = &TargetX86Base<TraitsType>::_sub;
+ Op_Hi = &TargetX86Base<TraitsType>::_sbb;
break;
}
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, Dest->getType());
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Dest->getType());
constexpr bool Locked = true;
Variable *T = nullptr;
_mov(T, Val);
@@ -3757,18 +3744,18 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
// xadd is probably fine vs lock add for add, and xchg is fine
// vs an atomic store.
NeedsCmpxchg = true;
- Op_Lo = &TargetX86Base<Machine>::_or;
- Op_Hi = &TargetX86Base<Machine>::_or;
+ Op_Lo = &TargetX86Base<TraitsType>::_or;
+ Op_Hi = &TargetX86Base<TraitsType>::_or;
break;
case Intrinsics::AtomicAnd:
NeedsCmpxchg = true;
- Op_Lo = &TargetX86Base<Machine>::_and;
- Op_Hi = &TargetX86Base<Machine>::_and;
+ Op_Lo = &TargetX86Base<TraitsType>::_and;
+ Op_Hi = &TargetX86Base<TraitsType>::_and;
break;
case Intrinsics::AtomicXor:
NeedsCmpxchg = true;
- Op_Lo = &TargetX86Base<Machine>::_xor;
- Op_Hi = &TargetX86Base<Machine>::_xor;
+ Op_Lo = &TargetX86Base<TraitsType>::_xor;
+ Op_Hi = &TargetX86Base<TraitsType>::_xor;
break;
case Intrinsics::AtomicExchange:
if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
@@ -3779,8 +3766,7 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
Op_Hi = nullptr;
break;
}
- typename Traits::X86OperandMem *Addr =
- formMemoryOperand(Ptr, Dest->getType());
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Dest->getType());
Variable *T = nullptr;
_mov(T, Val);
_xchg(Addr, T);
@@ -3793,12 +3779,12 @@ void TargetX86Base<Machine>::lowerAtomicRMW(Variable *Dest, uint32_t Operation,
expandAtomicRMWAsCmpxchg(Op_Lo, Op_Hi, Dest, Ptr, Val);
}
-template <class Machine>
-void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
- LowerBinOp Op_Hi,
- Variable *Dest,
- Operand *Ptr,
- Operand *Val) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
+ LowerBinOp Op_Hi,
+ Variable *Dest,
+ Operand *Ptr,
+ Operand *Val) {
// Expand a more complex RMW operation as a cmpxchg loop:
// For 64-bit:
// mov eax, [ptr]
@@ -3828,13 +3814,12 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
if (!Traits::Is64Bit && Ty == IceType_i64) {
Variable *T_edx = makeReg(IceType_i32, Traits::RegisterSet::Reg_edx);
Variable *T_eax = makeReg(IceType_i32, Traits::RegisterSet::Reg_eax);
- typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
+ 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);
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
const bool IsXchg8b = Op_Lo == nullptr && Op_Hi == nullptr;
if (!IsXchg8b) {
Context.insert(Label);
@@ -3876,7 +3861,7 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
_mov(DestHi, T_edx);
return;
}
- typename Traits::X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
+ X86OperandMem *Addr = formMemoryOperand(Ptr, Ty);
int32_t Eax;
switch (Ty) {
default:
@@ -3896,7 +3881,7 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
}
Variable *T_eax = makeReg(Ty, Eax);
_mov(T_eax, Addr);
- auto *Label = Context.insert<typename Traits::Insts::Label>(this);
+ auto *Label = Context.insert<InstX86Label>(this);
// We want to pick a different register for T than Eax, so don't use
// _mov(T == nullptr, T_eax).
Variable *T = makeReg(Ty);
@@ -3920,10 +3905,11 @@ void TargetX86Base<Machine>::expandAtomicRMWAsCmpxchg(LowerBinOp Op_Lo,
///
/// We could do constant folding here, but that should have
/// been done by the front-end/middle-end optimizations.
-template <class Machine>
-void TargetX86Base<Machine>::lowerCountZeros(bool Cttz, Type Ty, Variable *Dest,
- Operand *FirstVal,
- Operand *SecondVal) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty,
+ Variable *Dest,
+ Operand *FirstVal,
+ Operand *SecondVal) {
// TODO(jvoung): Determine if the user CPU supports LZCNT (BMI).
// Then the instructions will handle the Val == 0 case much more simply
// and won't require conversion from bit position to number of zeros.
@@ -3995,10 +3981,10 @@ void TargetX86Base<Machine>::lowerCountZeros(bool Cttz, Type Ty, Variable *Dest,
_mov(DestHi, Ctx->getConstantZero(IceType_i32));
}
-template <class Machine>
-void TargetX86Base<Machine>::typedLoad(Type Ty, Variable *Dest, Variable *Base,
- Constant *Offset) {
- auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::typedLoad(Type Ty, Variable *Dest,
+ Variable *Base, Constant *Offset) {
+ auto *Mem = X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
_movp(Dest, Mem);
@@ -4008,10 +3994,10 @@ void TargetX86Base<Machine>::typedLoad(Type Ty, Variable *Dest, Variable *Base,
_mov(Dest, Mem);
}
-template <class Machine>
-void TargetX86Base<Machine>::typedStore(Type Ty, Variable *Value,
- Variable *Base, Constant *Offset) {
- auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::typedStore(Type Ty, Variable *Value,
+ Variable *Base, Constant *Offset) {
+ auto *Mem = X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty))
_storep(Value, Mem);
@@ -4021,9 +4007,9 @@ void TargetX86Base<Machine>::typedStore(Type Ty, Variable *Value,
_store(Value, Mem);
}
-template <class Machine>
-void TargetX86Base<Machine>::copyMemory(Type Ty, Variable *Dest, Variable *Src,
- int32_t OffsetAmt) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::copyMemory(Type Ty, Variable *Dest,
+ Variable *Src, int32_t OffsetAmt) {
Constant *Offset = OffsetAmt ? Ctx->getConstantInt32(OffsetAmt) : nullptr;
// TODO(ascull): this or add nullptr test to _movp, _movq
Variable *Data = makeReg(Ty);
@@ -4032,9 +4018,9 @@ void TargetX86Base<Machine>::copyMemory(Type Ty, Variable *Dest, Variable *Src,
typedStore(Ty, Data, Dest, Offset);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerMemcpy(Operand *Dest, Operand *Src,
- Operand *Count) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerMemcpy(Operand *Dest, Operand *Src,
+ Operand *Count) {
// There is a load and store for each chunk in the unroll
constexpr uint32_t BytesPerStorep = 16;
@@ -4086,9 +4072,9 @@ void TargetX86Base<Machine>::lowerMemcpy(Operand *Dest, Operand *Src,
lowerCall(Call);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerMemmove(Operand *Dest, Operand *Src,
- Operand *Count) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerMemmove(Operand *Dest, Operand *Src,
+ Operand *Count) {
// There is a load and store for each chunk in the unroll
constexpr uint32_t BytesPerStorep = 16;
@@ -4158,9 +4144,9 @@ void TargetX86Base<Machine>::lowerMemmove(Operand *Dest, Operand *Src,
lowerCall(Call);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerMemset(Operand *Dest, Operand *Val,
- Operand *Count) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val,
+ Operand *Count) {
constexpr uint32_t BytesPerStorep = 16;
constexpr uint32_t BytesPerStoreq = 8;
constexpr uint32_t BytesPerStorei32 = 4;
@@ -4193,7 +4179,7 @@ void TargetX86Base<Machine>::lowerMemset(Operand *Dest, Operand *Val,
Constant *Offset = OffsetAmt ? Ctx->getConstantInt32(OffsetAmt) : nullptr;
// TODO(ascull): is 64-bit better with vector or scalar movq?
- auto *Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+ auto *Mem = X86OperandMem::create(Func, Ty, Base, Offset);
if (isVectorType(Ty)) {
assert(VecReg != nullptr);
_storep(VecReg, Mem);
@@ -4267,8 +4253,8 @@ void TargetX86Base<Machine>::lowerMemset(Operand *Dest, Operand *Val,
lowerCall(Call);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerIndirectJump(Variable *JumpTarget) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerIndirectJump(Variable *JumpTarget) {
const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
if (Traits::Is64Bit) {
Variable *T = makeReg(IceType_i64);
@@ -4665,11 +4651,11 @@ inline bool computeAddressOpt(Cfg *Func, const Inst *Instr,
///
/// Also note that we don't need to add a bounds check to a dereference of a
/// simple global variable address.
-template <class Machine>
-void TargetX86Base<Machine>::doMockBoundsCheck(Operand *Opnd) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::doMockBoundsCheck(Operand *Opnd) {
if (!Ctx->getFlags().getMockBoundsCheck())
return;
- if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Opnd)) {
+ if (auto *Mem = llvm::dyn_cast<X86OperandMem>(Opnd)) {
if (Mem->getIndex()) {
llvm::report_fatal_error("doMockBoundsCheck: Opnd contains index reg");
}
@@ -4686,7 +4672,7 @@ void TargetX86Base<Machine>::doMockBoundsCheck(Operand *Opnd) {
if (Var->getRegNum() == static_cast<int32_t>(getStackReg()))
return;
- auto *Label = Traits::Insts::Label::create(Func, this);
+ auto *Label = InstX86Label::create(Func, this);
_cmp(Opnd, Ctx->getConstantZero(IceType_i32));
_br(Traits::Cond::Br_e, Label);
_cmp(Opnd, Ctx->getConstantInt32(1));
@@ -4694,12 +4680,12 @@ void TargetX86Base<Machine>::doMockBoundsCheck(Operand *Opnd) {
Context.insert(Label);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerLoad(const InstLoad *Load) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerLoad(const InstLoad *Load) {
// A Load instruction can be treated the same as an Assign instruction, after
- // the source operand is transformed into an Traits::X86OperandMem operand.
+ // the source operand is transformed into an X86OperandMem operand.
// Note that the address mode optimization already creates an
- // Traits::X86OperandMem operand, so it doesn't need another level of
+ // X86OperandMem operand, so it doesn't need another level of
// transformation.
Variable *DestLoad = Load->getDest();
Type Ty = DestLoad->getType();
@@ -4709,7 +4695,8 @@ void TargetX86Base<Machine>::lowerLoad(const InstLoad *Load) {
lowerAssign(Assign);
}
-template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::doAddressOptLoad() {
Inst *Inst = Context.getCur();
Variable *Dest = Inst->getDest();
Operand *Addr = Inst->getSrc(0);
@@ -4719,10 +4706,9 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
int32_t Offset = 0;
// 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
+ // other X86OperandMem, so there should be no mention of segment
// registers there either.
- const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
- Traits::X86OperandMem::DefaultSegment;
+ const SegmentRegisters SegmentReg = X86OperandMem::DefaultSegment;
auto *Base = llvm::dyn_cast<Variable>(Addr);
if (computeAddressOpt(Func, Inst, Relocatable, Offset, Base, Index, Shift)) {
Inst->setDeleted();
@@ -4734,28 +4720,28 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptLoad() {
Relocatable->getName(),
Relocatable->getSuppressMangling());
}
- Addr = Traits::X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp,
- Index, Shift, SegmentReg);
+ Addr = X86OperandMem::create(Func, Dest->getType(), Base, OffsetOp, Index,
+ Shift, SegmentReg);
Context.insert<InstLoad>(Dest, Addr);
}
}
-template <class Machine>
-void TargetX86Base<Machine>::randomlyInsertNop(float Probability,
- RandomNumberGenerator &RNG) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::randomlyInsertNop(float Probability,
+ RandomNumberGenerator &RNG) {
RandomNumberGeneratorWrapper RNGW(RNG);
if (RNGW.getTrueWithProbability(Probability)) {
_nop(RNGW(Traits::X86_NUM_NOP_VARIANTS));
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerPhi(const InstPhi * /*Inst*/) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerPhi(const InstPhi * /*Inst*/) {
Func->setError("Phi found in regular instruction list");
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerSelect(const InstSelect *Select) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerSelect(const InstSelect *Select) {
Variable *Dest = Select->getDest();
if (isVectorType(Dest->getType())) {
@@ -4787,20 +4773,19 @@ void TargetX86Base<Machine>::lowerSelect(const InstSelect *Select) {
_cmp(CmpResult, Zero);
Operand *SrcT = Select->getTrueOperand();
Operand *SrcF = Select->getFalseOperand();
- const typename Traits::Cond::BrCond Cond = Traits::Cond::Br_ne;
+ const BrCond Cond = Traits::Cond::Br_ne;
lowerSelectMove(Dest, Cond, SrcT, SrcF);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerSelectMove(Variable *Dest,
- typename Traits::Cond::BrCond Cond,
- Operand *SrcT, Operand *SrcF) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerSelectMove(Variable *Dest, BrCond Cond,
+ Operand *SrcT, Operand *SrcF) {
Type DestTy = Dest->getType();
if (typeWidthInBytes(DestTy) == 1 || isFloatingType(DestTy)) {
// 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:
- auto *Label = Traits::Insts::Label::create(Func, this);
+ auto *Label = InstX86Label::create(Func, this);
SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
_mov(Dest, SrcT);
_br(Cond, Label);
@@ -4815,7 +4800,7 @@ void TargetX86Base<Machine>::lowerSelectMove(Variable *Dest,
// mov t, SrcT; cmov_!cond t, SrcF; mov dest, t
if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) {
std::swap(SrcT, SrcF);
- Cond = InstX86Base<Machine>::getOppositeCondition(Cond);
+ Cond = InstImpl<TraitsType>::InstX86Base::getOppositeCondition(Cond);
}
if (!Traits::Is64Bit && DestTy == IceType_i64) {
SrcT = legalizeUndef(SrcT);
@@ -4834,10 +4819,10 @@ void TargetX86Base<Machine>::lowerSelectMove(Variable *Dest,
lowerSelectIntMove(Dest, Cond, SrcT, SrcF);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerSelectIntMove(
- Variable *Dest, typename Traits::Cond::BrCond Cond, Operand *SrcT,
- Operand *SrcF) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerSelectIntMove(Variable *Dest, BrCond Cond,
+ Operand *SrcT,
+ Operand *SrcF) {
Variable *T = nullptr;
SrcF = legalize(SrcF);
_mov(T, SrcF);
@@ -4846,9 +4831,9 @@ void TargetX86Base<Machine>::lowerSelectIntMove(
_mov(Dest, T);
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerMove(Variable *Dest, Operand *Src,
- bool IsRedefinition) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerMove(Variable *Dest, Operand *Src,
+ bool IsRedefinition) {
assert(Dest->getType() == Src->getType());
assert(!Dest->isRematerializable());
if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
@@ -4882,9 +4867,9 @@ void TargetX86Base<Machine>::lowerMove(Variable *Dest, Operand *Src,
}
}
-template <class Machine>
-bool TargetX86Base<Machine>::lowerOptimizeFcmpSelect(const InstFcmp *Fcmp,
- const InstSelect *Select) {
+template <typename TraitsType>
+bool TargetX86Base<TraitsType>::lowerOptimizeFcmpSelect(
+ const InstFcmp *Fcmp, const InstSelect *Select) {
Operand *CmpSrc0 = Fcmp->getSrc(0);
Operand *CmpSrc1 = Fcmp->getSrc(1);
Operand *SelectSrcT = Select->getTrueOperand();
@@ -4911,8 +4896,8 @@ bool TargetX86Base<Machine>::lowerOptimizeFcmpSelect(const InstFcmp *Fcmp,
return false;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Icmp) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerIcmp(const InstIcmp *Icmp) {
Variable *Dest = Icmp->getDest();
if (isVectorType(Dest->getType())) {
lowerIcmpVector(Icmp);
@@ -4922,8 +4907,8 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Icmp) {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerSelectVector(const InstSelect *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerSelectVector(const InstSelect *Inst) {
Variable *Dest = Inst->getDest();
Type DestTy = Dest->getType();
Operand *SrcT = Inst->getTrueOperand();
@@ -4990,12 +4975,11 @@ void TargetX86Base<Machine>::lowerSelectVector(const InstSelect *Inst) {
return;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerStore(const InstStore *Inst) {
Operand *Value = Inst->getData();
Operand *Addr = Inst->getAddr();
- typename Traits::X86OperandMem *NewAddr =
- formMemoryOperand(Addr, Value->getType());
+ X86OperandMem *NewAddr = formMemoryOperand(Addr, Value->getType());
doMockBoundsCheck(NewAddr);
Type Ty = NewAddr->getType();
@@ -5003,10 +4987,8 @@ void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) {
Value = legalizeUndef(Value);
Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm);
Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm);
- _store(ValueHi,
- llvm::cast<typename Traits::X86OperandMem>(hiOperand(NewAddr)));
- _store(ValueLo,
- llvm::cast<typename Traits::X86OperandMem>(loOperand(NewAddr)));
+ _store(ValueHi, llvm::cast<X86OperandMem>(hiOperand(NewAddr)));
+ _store(ValueLo, llvm::cast<X86OperandMem>(loOperand(NewAddr)));
} else if (isVectorType(Ty)) {
_storep(legalizeToReg(Value), NewAddr);
} else {
@@ -5015,7 +4997,8 @@ void TargetX86Base<Machine>::lowerStore(const InstStore *Inst) {
}
}
-template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::doAddressOptStore() {
auto *Inst = llvm::cast<InstStore>(Context.getCur());
Operand *Data = Inst->getData();
Operand *Addr = Inst->getAddr();
@@ -5026,10 +5009,9 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
auto *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 Traits::X86OperandMem, so there should be no mention of segment
+ // other X86OperandMem, so there should be no mention of segment
// registers there either.
- const typename Traits::X86OperandMem::SegmentRegisters SegmentReg =
- Traits::X86OperandMem::DefaultSegment;
+ const SegmentRegisters SegmentReg = X86OperandMem::DefaultSegment;
if (computeAddressOpt(Func, Inst, Relocatable, Offset, Base, Index, Shift)) {
Inst->setDeleted();
Constant *OffsetOp = nullptr;
@@ -5040,17 +5022,17 @@ template <class Machine> void TargetX86Base<Machine>::doAddressOptStore() {
Relocatable->getName(),
Relocatable->getSuppressMangling());
}
- Addr = Traits::X86OperandMem::create(Func, Data->getType(), Base, OffsetOp,
- Index, Shift, SegmentReg);
+ Addr = X86OperandMem::create(Func, Data->getType(), Base, OffsetOp, Index,
+ Shift, SegmentReg);
auto *NewStore = Context.insert<InstStore>(Data, Addr);
if (Inst->getDest())
NewStore->setRmwBeacon(Inst->getRmwBeacon());
}
}
-template <class Machine>
-Operand *TargetX86Base<Machine>::lowerCmpRange(Operand *Comparison,
- uint64_t Min, uint64_t Max) {
+template <typename TraitsType>
+Operand *TargetX86Base<TraitsType>::lowerCmpRange(Operand *Comparison,
+ uint64_t Min, uint64_t Max) {
// TODO(ascull): 64-bit should not reach here but only because it is not
// implemented yet. This should be able to handle the 64-bit case.
assert(Traits::Is64Bit || Comparison->getType() != IceType_i64);
@@ -5068,19 +5050,20 @@ Operand *TargetX86Base<Machine>::lowerCmpRange(Operand *Comparison,
return Comparison;
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerCaseCluster(const CaseCluster &Case,
- Operand *Comparison, bool DoneCmp,
- CfgNode *DefaultTarget) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerCaseCluster(const CaseCluster &Case,
+ Operand *Comparison,
+ bool DoneCmp,
+ CfgNode *DefaultTarget) {
switch (Case.getKind()) {
case CaseCluster::JumpTable: {
- typename Traits::Insts::Label *SkipJumpTable;
+ InstX86Label *SkipJumpTable;
Operand *RangeIndex =
lowerCmpRange(Comparison, Case.getLow(), Case.getHigh());
if (DefaultTarget == nullptr) {
// Skip over jump table logic if comparison not in range and no default
- SkipJumpTable = Traits::Insts::Label::create(Func, this);
+ SkipJumpTable = InstX86Label::create(Func, this);
_br(Traits::Cond::Br_a, SkipJumpTable);
} else {
_br(Traits::Cond::Br_a, DefaultTarget);
@@ -5107,7 +5090,7 @@ void TargetX86Base<Machine>::lowerCaseCluster(const CaseCluster &Case,
Constant *Offset = nullptr;
uint16_t Shift = typeWidthInBytesLog2(getPointerType());
// TODO(ascull): remove need for legalize by allowing null base in memop
- auto *TargetInMemory = Traits::X86OperandMem::create(
+ auto *TargetInMemory = X86OperandMem::create(
Func, getPointerType(), legalizeToReg(Base), Offset, Index, Shift);
Variable *Target = nullptr;
_mov(Target, TargetInMemory);
@@ -5143,8 +5126,8 @@ void TargetX86Base<Machine>::lowerCaseCluster(const CaseCluster &Case,
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerSwitch(const InstSwitch *Inst) {
// Group cases together and navigate through them with a binary search
CaseClusterArray CaseClusters = CaseCluster::clusterizeSwitch(Func, Inst);
Operand *Src0 = Inst->getComparison();
@@ -5170,8 +5153,7 @@ 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);
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
_cmp(Src0Lo, ValueLo);
_br(Traits::Cond::Br_ne, Label);
_cmp(Src0Hi, ValueHi);
@@ -5206,12 +5188,12 @@ void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) {
// A span is over the clusters
struct SearchSpan {
- SearchSpan(SizeT Begin, SizeT Size, typename Traits::Insts::Label *Label)
+ SearchSpan(SizeT Begin, SizeT Size, InstX86Label *Label)
: Begin(Begin), Size(Size), Label(Label) {}
SizeT Begin;
SizeT Size;
- typename Traits::Insts::Label *Label;
+ InstX86Label *Label;
};
// The stack will only grow to the height of the tree so 12 should be plenty
std::stack<SearchSpan, llvm::SmallVector<SearchSpan, 12>> SearchSpanStack;
@@ -5265,11 +5247,10 @@ void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) {
SizeT PivotIndex = Span.Begin + (Span.Size / 2);
const CaseCluster &Pivot = CaseClusters[PivotIndex];
Constant *Value = Ctx->getConstantInt32(Pivot.getLow());
- typename Traits::Insts::Label *Label =
- Traits::Insts::Label::create(Func, this);
+ InstX86Label *Label = InstX86Label::create(Func, this);
_cmp(Comparison, Value);
// TODO(ascull): does it alway have to be far?
- _br(Traits::Cond::Br_b, Label, Traits::Insts::Br::Far);
+ _br(Traits::Cond::Br_b, Label, InstX86Br::Far);
// Lower the left and (pivot+right) sides, falling through to the right
SearchSpanStack.emplace(Span.Begin, Span.Size / 2, Label);
SearchSpanStack.emplace(PivotIndex, Span.Size - (Span.Size / 2), nullptr);
@@ -5281,10 +5262,11 @@ void TargetX86Base<Machine>::lowerSwitch(const InstSwitch *Inst) {
_br(DefaultTarget);
}
-template <class Machine>
-void TargetX86Base<Machine>::scalarizeArithmetic(InstArithmetic::OpKind Kind,
- Variable *Dest, Operand *Src0,
- Operand *Src1) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::scalarizeArithmetic(InstArithmetic::OpKind Kind,
+ Variable *Dest,
+ Operand *Src0,
+ Operand *Src1) {
assert(isVectorType(Dest->getType()));
Type Ty = Dest->getType();
Type ElementTy = typeElementType(Ty);
@@ -5323,8 +5305,8 @@ void TargetX86Base<Machine>::scalarizeArithmetic(InstArithmetic::OpKind Kind,
/// We can eliminate the sext operation by copying the result of pcmpeqd,
/// pcmpgtd, or cmpps (which produce sign extended results) to the result of the
/// sext operation.
-template <class Machine>
-void TargetX86Base<Machine>::eliminateNextVectorSextInstruction(
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::eliminateNextVectorSextInstruction(
Variable *SignExtendedResult) {
if (auto *NextCast =
llvm::dyn_cast_or_null<InstCast>(Context.getNextInst())) {
@@ -5338,8 +5320,8 @@ void TargetX86Base<Machine>::eliminateNextVectorSextInstruction(
}
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerUnreachable(
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerUnreachable(
const InstUnreachable * /*Inst*/) {
_ud2();
// Add a fake use of esp to make sure esp adjustments after the unreachable
@@ -5347,9 +5329,8 @@ void TargetX86Base<Machine>::lowerUnreachable(
keepEspLiveAtExit();
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerRMW(
- const typename Traits::Insts::FakeRMW *RMW) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerRMW(const InstX86FakeRMW *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 still there, either because the
@@ -5360,16 +5341,14 @@ void TargetX86Base<Machine>::lowerRMW(
return;
Operand *Src = RMW->getData();
Type Ty = Src->getType();
- typename Traits::X86OperandMem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
+ X86OperandMem *Addr = formMemoryOperand(RMW->getAddr(), Ty);
doMockBoundsCheck(Addr);
if (!Traits::Is64Bit && Ty == IceType_i64) {
Src = legalizeUndef(Src);
Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm);
Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm);
- typename Traits::X86OperandMem *AddrLo =
- llvm::cast<typename Traits::X86OperandMem>(loOperand(Addr));
- typename Traits::X86OperandMem *AddrHi =
- llvm::cast<typename Traits::X86OperandMem>(hiOperand(Addr));
+ X86OperandMem *AddrLo = llvm::cast<X86OperandMem>(loOperand(Addr));
+ X86OperandMem *AddrHi = llvm::cast<X86OperandMem>(hiOperand(Addr));
switch (RMW->getOp()) {
default:
// TODO(stichnot): Implement other arithmetic operators.
@@ -5427,10 +5406,9 @@ void TargetX86Base<Machine>::lowerRMW(
llvm::report_fatal_error("Couldn't lower RMW instruction");
}
-template <class Machine>
-void TargetX86Base<Machine>::lowerOther(const Inst *Instr) {
- if (const auto *RMW =
- llvm::dyn_cast<typename Traits::Insts::FakeRMW>(Instr)) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::lowerOther(const Inst *Instr) {
+ if (const auto *RMW = llvm::dyn_cast<InstX86FakeRMW>(Instr)) {
lowerRMW(RMW);
} else {
TargetLowering::lowerOther(Instr);
@@ -5440,7 +5418,7 @@ void TargetX86Base<Machine>::lowerOther(const Inst *Instr) {
/// Turn an i64 Phi instruction into a pair of i32 Phi instructions, to preserve
/// integrity of liveness analysis. Undef values are also turned into zeroes,
/// since loOperand() and hiOperand() don't expect Undef input.
-template <class Machine> void TargetX86Base<Machine>::prelowerPhis() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::prelowerPhis() {
if (Traits::Is64Bit) {
// On x86-64 we don't need to prelower phis -- the architecture can handle
// 64-bit integer natively.
@@ -5450,12 +5428,12 @@ template <class Machine> void TargetX86Base<Machine>::prelowerPhis() {
// Pause constant blinding or pooling, blinding or pooling will be done later
// during phi lowering assignments
BoolFlagSaver B(RandomizationPoolingPaused, true);
- PhiLowering::prelowerPhis32Bit<TargetX86Base<Machine>>(
+ PhiLowering::prelowerPhis32Bit<TargetX86Base<TraitsType>>(
this, Context.getNode(), Func);
}
-template <class Machine>
-void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::genTargetHelperCallFor(Inst *Instr) {
uint32_t StackArgumentsSize = 0;
if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) {
const char *HelperName = nullptr;
@@ -5680,8 +5658,8 @@ void TargetX86Base<Machine>::genTargetHelperCallFor(Inst *Instr) {
updateMaxOutArgsSizeBytes(StackArgumentsSize);
}
-template <class Machine>
-uint32_t TargetX86Base<Machine>::getCallStackArgumentsSizeBytes(
+template <typename TraitsType>
+uint32_t TargetX86Base<TraitsType>::getCallStackArgumentsSizeBytes(
const std::vector<Type> &ArgTypes, Type ReturnType) {
uint32_t OutArgumentsSizeBytes = 0;
uint32_t XmmArgCount = 0;
@@ -5715,9 +5693,9 @@ uint32_t TargetX86Base<Machine>::getCallStackArgumentsSizeBytes(
return OutArgumentsSizeBytes;
}
-template <class Machine>
-uint32_t
-TargetX86Base<Machine>::getCallStackArgumentsSizeBytes(const InstCall *Instr) {
+template <typename TraitsType>
+uint32_t TargetX86Base<TraitsType>::getCallStackArgumentsSizeBytes(
+ const InstCall *Instr) {
// Build a vector of the arguments' types.
std::vector<Type> ArgTypes;
for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
@@ -5732,8 +5710,9 @@ TargetX86Base<Machine>::getCallStackArgumentsSizeBytes(const InstCall *Instr) {
return getCallStackArgumentsSizeBytes(ArgTypes, ReturnType);
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeZeroedRegister(Type Ty,
+ int32_t RegNum) {
Variable *Reg = makeReg(Ty, RegNum);
switch (Ty) {
case IceType_i1:
@@ -5766,14 +5745,15 @@ Variable *TargetX86Base<Machine>::makeZeroedRegister(Type Ty, int32_t RegNum) {
// TODO(wala): Add limited support for vector constants so that complex
// initialization in registers is unnecessary.
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeVectorOfZeros(Type Ty, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeVectorOfZeros(Type Ty,
+ int32_t RegNum) {
return makeZeroedRegister(Ty, RegNum);
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty,
- int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeVectorOfMinusOnes(Type Ty,
+ int32_t RegNum) {
Variable *MinusOnes = makeReg(Ty, RegNum);
// Insert a FakeDef so the live range of MinusOnes is not overestimated.
Context.insert<InstFakeDef>(MinusOnes);
@@ -5781,17 +5761,17 @@ Variable *TargetX86Base<Machine>::makeVectorOfMinusOnes(Type Ty,
return MinusOnes;
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeVectorOfOnes(Type Ty, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeVectorOfOnes(Type Ty, int32_t RegNum) {
Variable *Dest = makeVectorOfZeros(Ty, RegNum);
Variable *MinusOne = makeVectorOfMinusOnes(Ty);
_psub(Dest, MinusOne);
return Dest;
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeVectorOfHighOrderBits(Type Ty,
- int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeVectorOfHighOrderBits(Type Ty,
+ int32_t RegNum) {
assert(Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v8i16 ||
Ty == IceType_v16i8);
if (Ty == IceType_v4f32 || Ty == IceType_v4i32 || Ty == IceType_v8i16) {
@@ -5817,18 +5797,18 @@ Variable *TargetX86Base<Machine>::makeVectorOfHighOrderBits(Type Ty,
/// ones logically right shifted one bit.
// TODO(stichnot): Fix the wala
// TODO: above, to represent vector constants in memory.
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeVectorOfFabsMask(Type Ty,
- int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeVectorOfFabsMask(Type Ty,
+ int32_t RegNum) {
Variable *Reg = makeVectorOfMinusOnes(Ty, RegNum);
_psrl(Reg, Ctx->getConstantInt8(1));
return Reg;
}
-template <class Machine>
-typename TargetX86Base<Machine>::Traits::X86OperandMem *
-TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
- uint32_t Offset) {
+template <typename TraitsType>
+typename TargetX86Base<TraitsType>::X86OperandMem *
+TargetX86Base<TraitsType>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
+ uint32_t Offset) {
// Ensure that Loc is a stack slot.
assert(Slot->mustNotHaveReg());
assert(Slot->getRegNum() == Variable::NoRegister);
@@ -5840,7 +5820,7 @@ TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
Variable *Loc = makeReg(PointerType);
_lea(Loc, Slot);
Constant *ConstantOffset = Ctx->getConstantInt32(Offset);
- return Traits::X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
+ return X86OperandMem::create(Func, Ty, Loc, ConstantOffset);
}
/// Lowering helper to copy a scalar integer source operand into some 8-bit GPR.
@@ -5871,8 +5851,8 @@ TargetX86Base<Machine>::getMemoryOperandForStackSlot(Type Ty, Variable *Slot,
/// Variable with the RCX86_IsTrunc8Rcvr register class. As such, this helper
/// is a convenient way to prevent ah/bh/ch/dh from being an (invalid) argument
/// to the pinsrb instruction.
-template <class Machine>
-Variable *TargetX86Base<Machine>::copyToReg8(Operand *Src, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::copyToReg8(Operand *Src, int32_t RegNum) {
Type Ty = Src->getType();
assert(isScalarIntegerType(Ty));
assert(Ty != IceType_i1);
@@ -5906,8 +5886,8 @@ Variable *TargetX86Base<Machine>::copyToReg8(Operand *Src, int32_t RegNum) {
/// Helper for legalize() to emit the right code to lower an operand to a
/// register of the appropriate type.
-template <class Machine>
-Variable *TargetX86Base<Machine>::copyToReg(Operand *Src, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::copyToReg(Operand *Src, int32_t RegNum) {
Type Ty = Src->getType();
Variable *Reg = makeReg(Ty, RegNum);
if (isVectorType(Ty)) {
@@ -5918,9 +5898,9 @@ Variable *TargetX86Base<Machine>::copyToReg(Operand *Src, int32_t RegNum) {
return Reg;
}
-template <class Machine>
-Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
- int32_t RegNum) {
+template <typename TraitsType>
+Operand *TargetX86Base<TraitsType>::legalize(Operand *From, LegalMask Allowed,
+ int32_t RegNum) {
Type Ty = From->getType();
// Assert that a physical register is allowed. To date, all calls to
// legalize() allow a physical register. If a physical register needs to be
@@ -5950,7 +5930,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
}
- if (auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(From)) {
+ if (auto *Mem = llvm::dyn_cast<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();
@@ -5966,9 +5946,8 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
legalize(Index, Legal_Reg | Legal_Rematerializable));
}
if (Base != RegBase || Index != RegIndex) {
- Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(),
- RegIndex, Mem->getShift(),
- Mem->getSegmentRegister());
+ Mem = X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(), RegIndex,
+ Mem->getShift(), Mem->getSegmentRegister());
}
// For all Memory Operands, we do randomization/pooling here
@@ -6025,7 +6004,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
llvm::cast<Constant>(From)->emitPoolLabel(StrBuf, Ctx);
llvm::cast<Constant>(From)->setShouldBePooled(true);
Constant *Offset = Ctx->getConstantSym(0, StrBuf.str(), true);
- From = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+ From = X86OperandMem::create(Func, Ty, Base, Offset);
}
bool NeedsReg = false;
if (!(Allowed & Legal_Imm) && !isScalarFloatingType(Ty))
@@ -6057,7 +6036,7 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
// Since Var is rematerializable, the offset will be added when the lea is
// emitted.
constexpr Constant *NoOffset = nullptr;
- auto *Mem = Traits::X86OperandMem::create(Func, Ty, Var, NoOffset);
+ auto *Mem = X86OperandMem::create(Func, Ty, Var, NoOffset);
_lea(NewVar, Mem);
From = NewVar;
} else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
@@ -6072,14 +6051,16 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed,
}
/// Provide a trivial wrapper to legalize() for this common usage.
-template <class Machine>
-Variable *TargetX86Base<Machine>::legalizeToReg(Operand *From, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::legalizeToReg(Operand *From,
+ int32_t RegNum) {
return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
}
/// Legalize undef values to concrete values.
-template <class Machine>
-Operand *TargetX86Base<Machine>::legalizeUndef(Operand *From, int32_t RegNum) {
+template <typename TraitsType>
+Operand *TargetX86Base<TraitsType>::legalizeUndef(Operand *From,
+ int32_t RegNum) {
Type Ty = From->getType();
if (llvm::isa<ConstantUndef>(From)) {
// Lower undefs to zero. Another option is to lower undefs to an
@@ -6105,9 +6086,9 @@ Operand *TargetX86Base<Machine>::legalizeUndef(Operand *From, int32_t RegNum) {
/// copied into a physical register. (Actually, either Src0 or Src1 can be
/// chosen for the physical register, but unfortunately we have to commit to one
/// or the other before register allocation.)
-template <class Machine>
-Operand *TargetX86Base<Machine>::legalizeSrc0ForCmp(Operand *Src0,
- Operand *Src1) {
+template <typename TraitsType>
+Operand *TargetX86Base<TraitsType>::legalizeSrc0ForCmp(Operand *Src0,
+ Operand *Src1) {
bool IsSrc1ImmOrReg = false;
if (llvm::isa<Constant>(Src1)) {
IsSrc1ImmOrReg = true;
@@ -6118,13 +6099,13 @@ Operand *TargetX86Base<Machine>::legalizeSrc0ForCmp(Operand *Src0,
return legalize(Src0, IsSrc1ImmOrReg ? (Legal_Reg | Legal_Mem) : Legal_Reg);
}
-template <class Machine>
-typename TargetX86Base<Machine>::Traits::X86OperandMem *
-TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
- bool DoLegalize) {
- auto *Mem = llvm::dyn_cast<typename Traits::X86OperandMem>(Opnd);
+template <typename TraitsType>
+typename TargetX86Base<TraitsType>::X86OperandMem *
+TargetX86Base<TraitsType>::formMemoryOperand(Operand *Opnd, Type Ty,
+ bool DoLegalize) {
+ auto *Mem = llvm::dyn_cast<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
+ // X86OperandMem, so in that case it wouldn't need another level of
// transformation.
if (!Mem) {
auto *Base = llvm::dyn_cast<Variable>(Opnd);
@@ -6144,16 +6125,16 @@ TargetX86Base<Machine>::formMemoryOperand(Operand *Opnd, Type Ty,
assert(llvm::isa<ConstantInteger32>(Offset) ||
llvm::isa<ConstantRelocatable>(Offset));
}
- Mem = Traits::X86OperandMem::create(Func, Ty, Base, Offset);
+ Mem = X86OperandMem::create(Func, Ty, Base, Offset);
}
// Do legalization, which contains randomization/pooling or do
// randomization/pooling.
- return llvm::cast<typename Traits::X86OperandMem>(
- DoLegalize ? legalize(Mem) : randomizeOrPoolImmediate(Mem));
+ return llvm::cast<X86OperandMem>(DoLegalize ? legalize(Mem)
+ : randomizeOrPoolImmediate(Mem));
}
-template <class Machine>
-Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) {
+template <typename TraitsType>
+Variable *TargetX86Base<TraitsType>::makeReg(Type Type, int32_t RegNum) {
// There aren't any 64-bit integer registers for x86-32.
assert(Traits::Is64Bit || Type != IceType_i64);
Variable *Reg = Func->makeVariable(Type);
@@ -6164,12 +6145,12 @@ Variable *TargetX86Base<Machine>::makeReg(Type Type, int32_t RegNum) {
return Reg;
}
-template <class Machine>
-const Type TargetX86Base<Machine>::TypeForSize[] = {
+template <typename TraitsType>
+const Type TargetX86Base<TraitsType>::TypeForSize[] = {
IceType_i8, IceType_i16, IceType_i32, IceType_f64, IceType_v16i8};
-template <class Machine>
-Type TargetX86Base<Machine>::largestTypeInSize(uint32_t Size,
- uint32_t MaxSize) {
+template <typename TraitsType>
+Type TargetX86Base<TraitsType>::largestTypeInSize(uint32_t Size,
+ uint32_t MaxSize) {
assert(Size != 0);
uint32_t TyIndex = llvm::findLastSet(Size, llvm::ZB_Undefined);
uint32_t MaxIndex = MaxSize == NoSizeLimit
@@ -6178,9 +6159,9 @@ Type TargetX86Base<Machine>::largestTypeInSize(uint32_t Size,
return TypeForSize[std::min(TyIndex, MaxIndex)];
}
-template <class Machine>
-Type TargetX86Base<Machine>::firstTypeThatFitsSize(uint32_t Size,
- uint32_t MaxSize) {
+template <typename TraitsType>
+Type TargetX86Base<TraitsType>::firstTypeThatFitsSize(uint32_t Size,
+ uint32_t MaxSize) {
assert(Size != 0);
uint32_t TyIndex = llvm::findLastSet(Size, llvm::ZB_Undefined);
if (!llvm::isPowerOf2_32(Size))
@@ -6191,31 +6172,31 @@ Type TargetX86Base<Machine>::firstTypeThatFitsSize(uint32_t Size,
return TypeForSize[std::min(TyIndex, MaxIndex)];
}
-template <class Machine> void TargetX86Base<Machine>::postLower() {
+template <typename TraitsType> void TargetX86Base<TraitsType>::postLower() {
if (Ctx->getFlags().getOptLevel() == Opt_m1)
return;
markRedefinitions();
Context.availabilityUpdate();
}
-template <class Machine>
-void TargetX86Base<Machine>::makeRandomRegisterPermutation(
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::makeRandomRegisterPermutation(
llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
Traits::makeRandomRegisterPermutation(Ctx, Func, Permutation,
ExcludeRegisters, Salt);
}
-template <class Machine>
-void TargetX86Base<Machine>::emit(const ConstantInteger32 *C) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emit(const ConstantInteger32 *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
Str << getConstantPrefix() << C->getValue();
}
-template <class Machine>
-void TargetX86Base<Machine>::emit(const ConstantInteger64 *C) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emit(const ConstantInteger64 *C) const {
if (!Traits::Is64Bit) {
llvm::report_fatal_error("Not expecting to emit 64-bit integers");
} else {
@@ -6226,31 +6207,32 @@ void TargetX86Base<Machine>::emit(const ConstantInteger64 *C) const {
}
}
-template <class Machine>
-void TargetX86Base<Machine>::emit(const ConstantFloat *C) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emit(const ConstantFloat *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
C->emitPoolLabel(Str, Ctx);
}
-template <class Machine>
-void TargetX86Base<Machine>::emit(const ConstantDouble *C) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emit(const ConstantDouble *C) const {
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
C->emitPoolLabel(Str, Ctx);
}
-template <class Machine>
-void TargetX86Base<Machine>::emit(const ConstantUndef *) const {
+template <typename TraitsType>
+void TargetX86Base<TraitsType>::emit(const ConstantUndef *) const {
llvm::report_fatal_error("undef value encountered by emitter.");
}
/// Randomize or pool an Immediate.
-template <class Machine>
-Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
- int32_t RegNum) {
+template <typename TraitsType>
+Operand *
+TargetX86Base<TraitsType>::randomizeOrPoolImmediate(Constant *Immediate,
+ int32_t RegNum) {
assert(llvm::isa<ConstantInteger32>(Immediate) ||
llvm::isa<ConstantRelocatable>(Immediate));
if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
@@ -6280,8 +6262,8 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
uint32_t Cookie = Func->getConstantBlindingCookie();
_mov(Reg, Ctx->getConstantInt(IceType_i32, Cookie + Value));
Constant *Offset = Ctx->getConstantInt(IceType_i32, 0 - Cookie);
- _lea(Reg, Traits::X86OperandMem::create(Func, IceType_i32, Reg, Offset,
- nullptr, 0));
+ _lea(Reg,
+ X86OperandMem::create(Func, IceType_i32, Reg, Offset, nullptr, 0));
if (Immediate->getType() != IceType_i32) {
Variable *TruncReg = makeReg(Immediate->getType(), RegNum);
_mov(TruncReg, Reg);
@@ -6310,9 +6292,8 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
constexpr bool SuppressMangling = true;
Constant *Symbol =
Ctx->getConstantSym(Offset, Label_stream.str(), SuppressMangling);
- typename Traits::X86OperandMem *MemOperand =
- Traits::X86OperandMem::create(Func, Immediate->getType(), nullptr,
- Symbol);
+ X86OperandMem *MemOperand =
+ X86OperandMem::create(Func, Immediate->getType(), nullptr, Symbol);
_mov(Reg, MemOperand);
return Reg;
}
@@ -6322,10 +6303,10 @@ Operand *TargetX86Base<Machine>::randomizeOrPoolImmediate(Constant *Immediate,
return Immediate;
}
-template <class Machine>
-typename TargetX86Base<Machine>::Traits::X86OperandMem *
-TargetX86Base<Machine>::randomizeOrPoolImmediate(
- typename Traits::X86OperandMem *MemOperand, int32_t RegNum) {
+template <typename TraitsType>
+typename TargetX86Base<TraitsType>::X86OperandMem *
+TargetX86Base<TraitsType>::randomizeOrPoolImmediate(X86OperandMem *MemOperand,
+ int32_t RegNum) {
assert(MemOperand);
if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_None ||
RandomizationPoolingPaused == true) {
@@ -6359,9 +6340,8 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
Constant *Mask2 =
Ctx->getConstantInt(MemOperand->getOffset()->getType(), 0 - Cookie);
- typename Traits::X86OperandMem *TempMemOperand =
- Traits::X86OperandMem::create(Func, MemOperand->getType(),
- MemOperand->getBase(), Mask1);
+ X86OperandMem *TempMemOperand = 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
@@ -6369,11 +6349,9 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
Variable *RegTemp = makeReg(MemOperand->getOffset()->getType(), RegNum);
_lea(RegTemp, TempMemOperand);
- typename Traits::X86OperandMem *NewMemOperand =
- Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
- Mask2, MemOperand->getIndex(),
- MemOperand->getShift(),
- MemOperand->getSegmentRegister());
+ X86OperandMem *NewMemOperand = X86OperandMem::create(
+ Func, MemOperand->getType(), RegTemp, Mask2, MemOperand->getIndex(),
+ MemOperand->getShift(), MemOperand->getSegmentRegister());
// Label this memory operand as randomized, so we won't randomize it
// again in case we call legalize() multiple times on this memory
@@ -6407,25 +6385,22 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
constexpr bool SuppressMangling = true;
Constant *Symbol = Ctx->getConstantSym(SymOffset, Label_stream.str(),
SuppressMangling);
- typename Traits::X86OperandMem *SymbolOperand =
- Traits::X86OperandMem::create(
- Func, MemOperand->getOffset()->getType(), nullptr, Symbol);
+ X86OperandMem *SymbolOperand = 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()) {
- typename Traits::X86OperandMem *CalculateOperand =
- Traits::X86OperandMem::create(
- Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
- RegTemp, 0, MemOperand->getSegmentRegister());
+ X86OperandMem *CalculateOperand = X86OperandMem::create(
+ Func, MemOperand->getType(), MemOperand->getBase(), nullptr,
+ RegTemp, 0, MemOperand->getSegmentRegister());
_lea(RegTemp, CalculateOperand);
}
- typename Traits::X86OperandMem *NewMemOperand =
- Traits::X86OperandMem::create(Func, MemOperand->getType(), RegTemp,
- nullptr, MemOperand->getIndex(),
- MemOperand->getShift(),
- MemOperand->getSegmentRegister());
+ X86OperandMem *NewMemOperand = X86OperandMem::create(
+ Func, MemOperand->getType(), RegTemp, nullptr,
+ MemOperand->getIndex(), MemOperand->getShift(),
+ MemOperand->getSegmentRegister());
return NewMemOperand;
}
assert("Unsupported -randomize-pool-immediates option" && false);
@@ -6436,7 +6411,7 @@ TargetX86Base<Machine>::randomizeOrPoolImmediate(
return MemOperand;
}
-} // end of namespace X86Internal
+} // end of namespace X86NAMESPACE
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H

Powered by Google App Engine
This is Rietveld 408576698