summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-11-18 00:16:44 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-11-18 00:16:44 +0000
commitc54aa9c844e15e1fc35c6dbf73392bd54aec45ed (patch)
treebafd3f55452f77d1cd5c2558f8352079a38f5b5f
parent0b44f44bcf70b15ba89e23a6a31440e2c4e6600e (diff)
downloadbcm5719-llvm-c54aa9c844e15e1fc35c6dbf73392bd54aec45ed.tar.gz
bcm5719-llvm-c54aa9c844e15e1fc35c6dbf73392bd54aec45ed.zip
[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
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td4
-rw-r--r--llvm/include/llvm/Target/Target.td10
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.cpp11
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.h6
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp5
5 files changed, 30 insertions, 6 deletions
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 6e6b5820d4b..557217c3456 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -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;
}
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 302ca34e07d..86fa3c03fb5 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -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;
diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp
index 8fa3050e078..44ee16f6fd7 100644
--- a/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -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
diff --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h
index e173e153879..9cff95b1247 100644
--- a/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/llvm/utils/TableGen/CodeGenInstruction.h
@@ -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;
};
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 56a638483c0..505864bb0d5 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -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.
OpenPOWER on IntegriCloud