diff --git a/include/llvm/CodeGen/SDNodeProperties.td b/include/llvm/CodeGen/SDNodeProperties.td new file mode 100644 index 00000000000..83bbab2fdc8 --- /dev/null +++ b/include/llvm/CodeGen/SDNodeProperties.td @@ -0,0 +1,34 @@ +//===- SDNodeProperties.td - Common code for DAG isels ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class SDNodeProperty; + +// Selection DAG Pattern Operations +class SDPatternOperator { + list Properties = []; +} + +//===----------------------------------------------------------------------===// +// Selection DAG Node Properties. +// +// Note: These are hard coded into tblgen. +// +def SDNPCommutative : SDNodeProperty; // X op Y == Y op X +def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) +def SDNPHasChain : SDNodeProperty; // R/W chain operand and result +def SDNPOutGlue : SDNodeProperty; // Write a flag result +def SDNPInGlue : SDNodeProperty; // Read a flag operand +def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand +def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. +def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. +def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. +def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand +def SDNPVariadic : SDNodeProperty; // Node has variable arguments. +def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match +def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 07de0568cab..a2a1f26292c 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// include "llvm/CodeGen/ValueTypes.td" +include "llvm/CodeGen/SDNodeProperties.td" //===----------------------------------------------------------------------===// // Properties we keep track of for intrinsics. @@ -264,16 +265,17 @@ def llvm_vararg_ty : LLVMType; // this means vararg here // intrinsic. // * Properties can be set to describe the behavior of the intrinsic. // -class SDPatternOperator; class Intrinsic ret_types, list param_types = [], - list properties = [], - string name = ""> : SDPatternOperator { + list intr_properties = [], + string name = "", + list sd_properties = []> : SDPatternOperator { string LLVMName = name; string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics. list RetTypes = ret_types; list ParamTypes = param_types; - list IntrProperties = properties; + list IntrProperties = intr_properties; + let Properties = sd_properties; bit isTarget = 0; } diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 06caa21d288..f6162377b8b 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -285,32 +285,6 @@ class SDCallSeqStart constraints> : class SDCallSeqEnd constraints> : SDTypeProfile<0, 2, constraints>; -//===----------------------------------------------------------------------===// -// Selection DAG Node Properties. -// -// Note: These are hard coded into tblgen. -// -class SDNodeProperty; -def SDNPCommutative : SDNodeProperty; // X op Y == Y op X -def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) -def SDNPHasChain : SDNodeProperty; // R/W chain operand and result -def SDNPOutGlue : SDNodeProperty; // Write a flag result -def SDNPInGlue : SDNodeProperty; // Read a flag operand -def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand -def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. -def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. -def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. -def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand -def SDNPVariadic : SDNodeProperty; // Node has variable arguments. -def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match -def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Operations -class SDPatternOperator { - list Properties = []; -} - //===----------------------------------------------------------------------===// // Selection DAG Node definitions. // diff --git a/test/TableGen/intrinsic-long-name.td b/test/TableGen/intrinsic-long-name.td index 24ed89ac4ac..9bbfe9829a6 100644 --- a/test/TableGen/intrinsic-long-name.td +++ b/test/TableGen/intrinsic-long-name.td @@ -2,6 +2,7 @@ // XFAIL: vg_leak class IntrinsicProperty; +class SDNodeProperty; class ValueType { string Namespace = "MVT"; @@ -20,6 +21,7 @@ class Intrinsic param_types = []> { list RetTypes = []; list ParamTypes = param_types; list IntrProperties = []; + list Properties = []; } def iAny : ValueType<0, 253>; diff --git a/test/TableGen/intrinsic-struct.td b/test/TableGen/intrinsic-struct.td index 93737b14db2..1f1a8c2c822 100644 --- a/test/TableGen/intrinsic-struct.td +++ b/test/TableGen/intrinsic-struct.td @@ -2,6 +2,7 @@ // XFAIL: vg_leak class IntrinsicProperty; +class SDNodeProperty; class ValueType { string Namespace = "MVT"; @@ -20,6 +21,7 @@ class Intrinsic ret_types = []> { list RetTypes = ret_types; list ParamTypes = []; list IntrProperties = []; + list Properties = []; } def iAny : ValueType<0, 253>; diff --git a/test/TableGen/intrinsic-varargs.td b/test/TableGen/intrinsic-varargs.td index 4b2cc5ae02f..48436477901 100644 --- a/test/TableGen/intrinsic-varargs.td +++ b/test/TableGen/intrinsic-varargs.td @@ -2,6 +2,7 @@ // XFAIL: vg_leak class IntrinsicProperty; +class SDNodeProperty; class ValueType { string Namespace = "MVT"; @@ -20,6 +21,7 @@ class Intrinsic param_types = []> { list RetTypes = []; list ParamTypes = param_types; list IntrProperties = []; + list Properties = []; } // isVoid needs to match the definition in ValueTypes.td diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index c84f4925aa7..0944d54a427 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -32,6 +32,7 @@ add_tablegen(llvm-tblgen LLVM PseudoLoweringEmitter.cpp RegisterBankEmitter.cpp RegisterInfoEmitter.cpp + SDNodeProperties.cpp SearchableTableEmitter.cpp SubtargetEmitter.cpp SubtargetFeatureInfo.cpp diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 51473f06da7..d23b45aab79 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1591,37 +1591,7 @@ SDNodeInfo::SDNodeInfo(Record *R, const CodeGenHwModes &CGH) : Def(R) { NumOperands = TypeProfile->getValueAsInt("NumOperands"); // Parse the properties. - Properties = 0; - for (Record *Property : R->getValueAsListOfDefs("Properties")) { - if (Property->getName() == "SDNPCommutative") { - Properties |= 1 << SDNPCommutative; - } else if (Property->getName() == "SDNPAssociative") { - Properties |= 1 << SDNPAssociative; - } else if (Property->getName() == "SDNPHasChain") { - Properties |= 1 << SDNPHasChain; - } else if (Property->getName() == "SDNPOutGlue") { - Properties |= 1 << SDNPOutGlue; - } else if (Property->getName() == "SDNPInGlue") { - Properties |= 1 << SDNPInGlue; - } else if (Property->getName() == "SDNPOptInGlue") { - Properties |= 1 << SDNPOptInGlue; - } else if (Property->getName() == "SDNPMayStore") { - Properties |= 1 << SDNPMayStore; - } else if (Property->getName() == "SDNPMayLoad") { - Properties |= 1 << SDNPMayLoad; - } else if (Property->getName() == "SDNPSideEffect") { - Properties |= 1 << SDNPSideEffect; - } else if (Property->getName() == "SDNPMemOperand") { - Properties |= 1 << SDNPMemOperand; - } else if (Property->getName() == "SDNPVariadic") { - Properties |= 1 << SDNPVariadic; - } else { - PrintFatalError("Unknown SD Node property '" + - Property->getName() + "' on node '" + - R->getName() + "'!"); - } - } - + Properties = parseSDPatternOperatorProperties(R); // Parse the type constraints. std::vector ConstraintList = @@ -2100,11 +2070,20 @@ bool TreePatternNode::NodeHasProperty(SDNP Property, if (isLeaf()) { if (const ComplexPattern *CP = getComplexPatternInfo(CGP)) return CP->hasProperty(Property); + return false; } - Record *Operator = getOperator(); - if (!Operator->isSubClassOf("SDNode")) return false; + if (Property != SDNPHasChain) { + // The chain proprety is already present on the different intrinsic node + // types (intrinsic_w_chain, intrinsic_void), and is not explicitly listed + // on the intrinsic. Anything else is specific to the individual intrinsic. + if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CGP)) + return Int->hasProperty(Property); + } + + if (!Operator->isSubClassOf("SDPatternOperator")) + return false; return CGP.getSDNodeInfo(Operator).hasProperty(Property); } diff --git a/utils/TableGen/CodeGenDAGPatterns.h b/utils/TableGen/CodeGenDAGPatterns.h index afbcb10a4b6..348ae4d06cb 100644 --- a/utils/TableGen/CodeGenDAGPatterns.h +++ b/utils/TableGen/CodeGenDAGPatterns.h @@ -18,6 +18,7 @@ #include "CodeGenHwModes.h" #include "CodeGenIntrinsics.h" #include "CodeGenTarget.h" +#include "SDNodeProperties.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" @@ -1204,6 +1205,7 @@ inline bool SDNodeInfo::ApplyTypeConstraints(TreePatternNode *N, MadeChange |= TypeConstraints[i].ApplyTypeConstraint(N, *this, TP); return MadeChange; } + } // end namespace llvm #endif diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h index 24374127f53..91305034dc2 100644 --- a/utils/TableGen/CodeGenIntrinsics.h +++ b/utils/TableGen/CodeGenIntrinsics.h @@ -14,6 +14,7 @@ #ifndef LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H #define LLVM_UTILS_TABLEGEN_CODEGENINTRINSICS_H +#include "SDNodeProperties.h" #include "llvm/CodeGen/MachineValueType.h" #include #include @@ -104,6 +105,9 @@ struct CodeGenIntrinsic { }; ModRefBehavior ModRef; + /// SDPatternOperator Properties applied to the intrinsic. + unsigned Properties; + /// This is set to true if the intrinsic is overloaded by its argument /// types. bool isOverloaded; @@ -133,6 +137,10 @@ struct CodeGenIntrinsic { enum ArgAttribute { NoCapture, Returned, ReadOnly, WriteOnly, ReadNone }; std::vector> ArgumentAttributes; + bool hasProperty(enum SDNP Prop) const { + return Properties & (1 << Prop); + } + CodeGenIntrinsic(Record *R); }; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 827b6083c17..168bd690831 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "CodeGenTarget.h" +#include "CodeGenDAGPatterns.h" #include "CodeGenIntrinsics.h" #include "CodeGenSchedule.h" #include "llvm/ADT/STLExtras.h" @@ -450,6 +451,7 @@ ComplexPattern::ComplexPattern(Record *R) { else Complexity = RawComplexity; + // FIXME: Why is this different from parseSDPatternOperatorProperties? // Parse the properties. Properties = 0; std::vector PropList = R->getValueAsListOfDefs("Properties"); @@ -512,6 +514,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { TheDef = R; std::string DefName = R->getName(); ModRef = ReadWriteMem; + Properties = 0; isOverloaded = false; isCommutative = false; canThrow = false; @@ -681,6 +684,10 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) { llvm_unreachable("Unknown property!"); } + // Also record the SDPatternOperator Properties. + Properties = parseSDPatternOperatorProperties(R); + // Sort the argument attributes for later benefit. std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end()); } + diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 89aa81b5fc3..7280d707fba 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -21,6 +21,7 @@ #include "CodeGenInstruction.h" #include "CodeGenRegisters.h" #include "InfoByHwMode.h" +#include "SDNodeProperties.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Record.h" #include @@ -31,25 +32,6 @@ struct CodeGenRegister; class CodeGenSchedModels; class CodeGenTarget; -// SelectionDAG node properties. -// SDNPMemOperand: indicates that a node touches memory and therefore must -// have an associated memory operand that describes the access. -enum SDNP { - SDNPCommutative, - SDNPAssociative, - SDNPHasChain, - SDNPOutGlue, - SDNPInGlue, - SDNPOptInGlue, - SDNPMayLoad, - SDNPMayStore, - SDNPSideEffect, - SDNPMemOperand, - SDNPVariadic, - SDNPWantRoot, - SDNPWantParent -}; - /// getValueType - Return the MVT::SimpleValueType that the specified TableGen /// record corresponds to. MVT::SimpleValueType getValueType(Record *Rec); diff --git a/utils/TableGen/SDNodeProperties.cpp b/utils/TableGen/SDNodeProperties.cpp new file mode 100644 index 00000000000..343febc99d1 --- /dev/null +++ b/utils/TableGen/SDNodeProperties.cpp @@ -0,0 +1,49 @@ +//===- SDNodeProperties.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SDNodeProperties.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" + +using namespace llvm; + +unsigned llvm::parseSDPatternOperatorProperties(Record *R) { + unsigned Properties = 0; + for (Record *Property : R->getValueAsListOfDefs("Properties")) { + if (Property->getName() == "SDNPCommutative") { + Properties |= 1 << SDNPCommutative; + } else if (Property->getName() == "SDNPAssociative") { + Properties |= 1 << SDNPAssociative; + } else if (Property->getName() == "SDNPHasChain") { + Properties |= 1 << SDNPHasChain; + } else if (Property->getName() == "SDNPOutGlue") { + Properties |= 1 << SDNPOutGlue; + } else if (Property->getName() == "SDNPInGlue") { + Properties |= 1 << SDNPInGlue; + } else if (Property->getName() == "SDNPOptInGlue") { + Properties |= 1 << SDNPOptInGlue; + } else if (Property->getName() == "SDNPMayStore") { + Properties |= 1 << SDNPMayStore; + } else if (Property->getName() == "SDNPMayLoad") { + Properties |= 1 << SDNPMayLoad; + } else if (Property->getName() == "SDNPSideEffect") { + Properties |= 1 << SDNPSideEffect; + } else if (Property->getName() == "SDNPMemOperand") { + Properties |= 1 << SDNPMemOperand; + } else if (Property->getName() == "SDNPVariadic") { + Properties |= 1 << SDNPVariadic; + } else { + PrintFatalError("Unknown SD Node property '" + + Property->getName() + "' on node '" + + R->getName() + "'!"); + } + } + + return Properties; +} diff --git a/utils/TableGen/SDNodeProperties.h b/utils/TableGen/SDNodeProperties.h new file mode 100644 index 00000000000..a8d4efb5dab --- /dev/null +++ b/utils/TableGen/SDNodeProperties.h @@ -0,0 +1,40 @@ +//===- SDNodeProperties.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_UTILS_TABLEGEN_SDNODEPROPERTIES_H +#define LLVM_UTILS_TABLEGEN_SDNODEPROPERTIES_H + +namespace llvm { + +class Record; + +// SelectionDAG node properties. +// SDNPMemOperand: indicates that a node touches memory and therefore must +// have an associated memory operand that describes the access. +enum SDNP { + SDNPCommutative, + SDNPAssociative, + SDNPHasChain, + SDNPOutGlue, + SDNPInGlue, + SDNPOptInGlue, + SDNPMayLoad, + SDNPMayStore, + SDNPSideEffect, + SDNPMemOperand, + SDNPVariadic, + SDNPWantRoot, + SDNPWantParent +}; + +unsigned parseSDPatternOperatorProperties(Record *R); + +} + +#endif