forked from OSchip/llvm-project
[globalisel][tablegen] Generalize pointer-type inference by introducing ptypeN. NFC
ptypeN is functionally the same as typeN except that it informs the SelectionDAG importer that an operand should be treated as a pointer even if it was written as iN. This is important for patterns that use iN instead of iPTR to represent pointers. E.g.: (set GPR64:$dst, (load GPR64:$addr)) Previously, this was handled as a hardcoded special case for the appropriate operands to G_LOAD and G_STORE. llvm-svn: 318574
This commit is contained in:
parent
0b44f44bcf
commit
c54aa9c844
|
@ -469,7 +469,7 @@ def G_FLOG2 : Instruction {
|
|||
// Generic load. Expects a MachineMemOperand in addition to explicit operands.
|
||||
def G_LOAD : Instruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type1:$addr);
|
||||
let InOperandList = (ins ptype1:$addr);
|
||||
let hasSideEffects = 0;
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
@ -477,7 +477,7 @@ def G_LOAD : Instruction {
|
|||
// Generic store. Expects a MachineMemOperand in addition to explicit operands.
|
||||
def G_STORE : Instruction {
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins type0:$src, type1:$addr);
|
||||
let InOperandList = (ins type0:$src, ptype1:$addr);
|
||||
let hasSideEffects = 0;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
|
|
@ -792,6 +792,7 @@ def f64imm : Operand<f64>;
|
|||
// have the same LLT).
|
||||
class TypedOperand<string Ty> : Operand<untyped> {
|
||||
let OperandType = Ty;
|
||||
bit IsPointer = 0;
|
||||
}
|
||||
|
||||
def type0 : TypedOperand<"OPERAND_GENERIC_0">;
|
||||
|
@ -801,6 +802,15 @@ def type3 : TypedOperand<"OPERAND_GENERIC_3">;
|
|||
def type4 : TypedOperand<"OPERAND_GENERIC_4">;
|
||||
def type5 : TypedOperand<"OPERAND_GENERIC_5">;
|
||||
|
||||
let IsPointer = 1 in {
|
||||
def ptype0 : TypedOperand<"OPERAND_GENERIC_0">;
|
||||
def ptype1 : TypedOperand<"OPERAND_GENERIC_1">;
|
||||
def ptype2 : TypedOperand<"OPERAND_GENERIC_2">;
|
||||
def ptype3 : TypedOperand<"OPERAND_GENERIC_3">;
|
||||
def ptype4 : TypedOperand<"OPERAND_GENERIC_4">;
|
||||
def ptype5 : TypedOperand<"OPERAND_GENERIC_5">;
|
||||
}
|
||||
|
||||
/// zero_reg definition - Special node to stand for the zero register.
|
||||
///
|
||||
def zero_reg;
|
||||
|
|
|
@ -430,6 +430,17 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
|
|||
return Res;
|
||||
}
|
||||
|
||||
bool CodeGenInstruction::isOperandAPointer(unsigned i) const {
|
||||
if (DagInit *ConstraintList = TheDef->getValueAsDag("InOperandList")) {
|
||||
if (i < ConstraintList->getNumArgs()) {
|
||||
if (DefInit *Constraint = dyn_cast<DefInit>(ConstraintList->getArg(i))) {
|
||||
return Constraint->getDef()->isSubClassOf("TypedOperand") &&
|
||||
Constraint->getDef()->getValueAsBit("IsPointer");
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// CodeGenInstAlias Implementation
|
||||
|
|
|
@ -284,6 +284,12 @@ template <typename T> class ArrayRef;
|
|||
/// include text from the specified variant, returning the new string.
|
||||
static std::string FlattenAsmStringVariants(StringRef AsmString,
|
||||
unsigned Variant);
|
||||
|
||||
// Is the specified operand in a generic instruction implicitly a pointer.
|
||||
// This can be used on intructions that use typeN or ptypeN to identify
|
||||
// operands that should be considered as pointers even though SelectionDAG
|
||||
// didn't make a distinction between integer and pointers.
|
||||
bool isOperandAPointer(unsigned i) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2546,10 +2546,7 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
|
|||
// SelectionDAG allows pointers to be represented with iN since it doesn't
|
||||
// distinguish between pointers and integers but they are different types in GlobalISel.
|
||||
// Coerce integers to pointers to address space 0 if the context indicates a pointer.
|
||||
// TODO: Find a better way to do this, SDTCisPtrTy?
|
||||
bool OperandIsAPointer =
|
||||
(SrcGIOrNull->TheDef->getName() == "G_LOAD" && i == 0) ||
|
||||
(SrcGIOrNull->TheDef->getName() == "G_STORE" && i == 1);
|
||||
bool OperandIsAPointer = SrcGIOrNull->isOperandAPointer(i);
|
||||
|
||||
// For G_INTRINSIC/G_INTRINSIC_W_SIDE_EFFECTS, the operand immediately
|
||||
// following the defs is an intrinsic ID.
|
||||
|
|
Loading…
Reference in New Issue