summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-06-16 20:29:38 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-06-16 20:29:38 +0000
commit6bd9567a6a1ba62118cdd258ddc52ea8f82ff511 (patch)
treeefa5e78092725455c72491bb166a2ad3aa9648a0 /utils
parent35b9a7790e904abce4e6dac3f1ed89696522f19a (diff)
downloadllvm-6bd9567a6a1ba62118cdd258ddc52ea8f82ff511.tar.gz
llvm-6bd9567a6a1ba62118cdd258ddc52ea8f82ff511.tar.bz2
llvm-6bd9567a6a1ba62118cdd258ddc52ea8f82ff511.tar.xz
- Add "Commutative" property to intrinsics. This allows tblgen to generate the commuted variants for dagisel matching code.
- Mark lots of X86 intrinsics as "Commutative" to allow load folding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52353 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp36
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.h4
-rw-r--r--utils/TableGen/CodeGenIntrinsics.h4
-rw-r--r--utils/TableGen/CodeGenTarget.cpp3
4 files changed, 42 insertions, 5 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 882c7245f6..44dbe6c95d 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -742,6 +742,15 @@ getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const {
return &CDP.getIntrinsicInfo(IID);
}
+/// isCommutativeIntrinsic - Return true if the node corresponds to a
+/// commutative intrinsic.
+bool
+TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
+ if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP))
+ return Int->isCommutative;
+ return false;
+}
+
/// ApplyTypeConstraints - Apply all of the type constraints relevent to
/// this node and its children in the tree. This returns true if it makes a
@@ -999,11 +1008,13 @@ bool TreePatternNode::canPatternMatch(std::string &Reason,
// If this node is a commutative operator, check that the LHS isn't an
// immediate.
const SDNodeInfo &NodeInfo = CDP.getSDNodeInfo(getOperator());
- if (NodeInfo.hasProperty(SDNPCommutative)) {
+ bool isCommIntrinsic = isCommutativeIntrinsic(CDP);
+ if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
// Scan all of the operands of the node and make sure that only the last one
// is a constant node, unless the RHS also is.
if (!OnlyOnRHSOfCommutative(getChild(getNumChildren()-1))) {
- for (unsigned i = 0, e = getNumChildren()-1; i != e; ++i)
+ bool Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
+ for (unsigned i = Skip, e = getNumChildren()-1; i != e; ++i)
if (OnlyOnRHSOfCommutative(getChild(i))) {
Reason="Immediate value must be on the RHS of commutative operators!";
return false;
@@ -2250,8 +2261,10 @@ static void GenerateVariantsOf(TreePatternNode *N,
CombineChildVariants(N, ChildVariants, OutVariants, CDP, DepVars);
// If this node is commutative, consider the commuted order.
- if (NodeInfo.hasProperty(SDNPCommutative)) {
- assert(N->getNumChildren()==2 &&"Commutative but doesn't have 2 children!");
+ bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
+ if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
+ assert((N->getNumChildren()==2 || isCommIntrinsic) &&
+ "Commutative but doesn't have 2 children!");
// Don't count children which are actually register references.
unsigned NC = 0;
for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
@@ -2265,7 +2278,20 @@ static void GenerateVariantsOf(TreePatternNode *N,
NC++;
}
// Consider the commuted order.
- if (NC == 2)
+ if (isCommIntrinsic) {
+ // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd
+ // operands are the commutative operands, and there might be more operands
+ // after those.
+ assert(NC >= 3 &&
+ "Commutative intrinsic should have at least 3 childrean!");
+ std::vector<std::vector<TreePatternNode*> > Variants;
+ Variants.push_back(ChildVariants[0]); // Intrinsic id.
+ Variants.push_back(ChildVariants[2]);
+ Variants.push_back(ChildVariants[1]);
+ for (unsigned i = 3; i != NC; ++i)
+ Variants.push_back(ChildVariants[i]);
+ CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
+ } else if (NC == 2)
CombineChildVariants(N, ChildVariants[1], ChildVariants[0],
OutVariants, CDP, DepVars);
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h
index 40cfa88cd2..50c39bcf16 100644
--- a/utils/TableGen/CodeGenDAGPatterns.h
+++ b/utils/TableGen/CodeGenDAGPatterns.h
@@ -221,6 +221,10 @@ public:
/// getIntrinsicInfo - If this node corresponds to an intrinsic, return the
/// CodeGenIntrinsic information for it, otherwise return a null pointer.
const CodeGenIntrinsic *getIntrinsicInfo(const CodeGenDAGPatterns &CDP) const;
+
+ /// isCommutativeIntrinsic - Return true if the node is an intrinsic which is
+ /// marked isCommutative.
+ bool isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const;
void print(std::ostream &OS) const;
void dump() const;
diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h
index a66c30b6cb..4de93864a8 100644
--- a/utils/TableGen/CodeGenIntrinsics.h
+++ b/utils/TableGen/CodeGenIntrinsics.h
@@ -49,6 +49,10 @@ namespace llvm {
// types.
bool isOverloaded;
+ // isCommutative - True if the intrinsic is commutative.
+ //
+ bool isCommutative;
+
CodeGenIntrinsic(Record *R);
};
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index a76f5cd55f..9b3864780d 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -404,6 +404,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
std::string DefName = R->getName();
ModRef = WriteMem;
isOverloaded = false;
+ isCommutative = false;
if (DefName.size() <= 4 ||
std::string(DefName.begin(), DefName.begin()+4) != "int_")
@@ -469,6 +470,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
ModRef = WriteArgMem;
else if (Property->getName() == "IntrWriteMem")
ModRef = WriteMem;
+ else if (Property->getName() == "Commutative")
+ isCommutative = true;
else
assert(0 && "Unknown property!");
}