Skip to content

Commit

Permalink
Reland [IR] Intrinsics default attributes and opt-out flag
Browse files Browse the repository at this point in the history
Intrinsic properties can now be set to default and applied to all
intrinsics. If the attributes are not needed, the user can opt-out by
setting the DisableDefaultAttributes flag to true.

Differential Revision: https://reviews.llvm.org/D70365
  • Loading branch information
sstefan1 committed Aug 26, 2020
1 parent 1f44dfb commit 99d18f7
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 75 deletions.
11 changes: 9 additions & 2 deletions llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ include "llvm/CodeGen/SDNodeProperties.td"
// Properties we keep track of for intrinsics.
//===----------------------------------------------------------------------===//

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

// Intr*Mem - Memory properties. If no property is set, the worst case
// is assumed (it may read and write any memory it can get access to and it may
Expand Down Expand Up @@ -331,14 +333,19 @@ class Intrinsic<list<LLVMType> ret_types,
list<LLVMType> param_types = [],
list<IntrinsicProperty> intr_properties = [],
string name = "",
list<SDNodeProperty> sd_properties = []> : SDPatternOperator {
list<SDNodeProperty> sd_properties = [],
bit disable_default_attributes = 0> : SDPatternOperator {
string LLVMName = name;
string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
list<LLVMType> RetTypes = ret_types;
list<LLVMType> ParamTypes = param_types;
list<IntrinsicProperty> IntrProperties = intr_properties;
let Properties = sd_properties;

// Disable applying IntrinsicProperties that are marked default with
// IntrinsicProperty<1>
bit DisableDefaultAttributes = disable_default_attributes;

bit isTarget = 0;
}

Expand Down
7 changes: 6 additions & 1 deletion llvm/test/TableGen/intrin-side-effects.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ class LLVMType<ValueType vt> {

def llvm_i32_ty : LLVMType<i32>;

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

def IntrNoMem : IntrinsicProperty;
def IntrHasSideEffects : IntrinsicProperty;

Expand All @@ -27,6 +30,8 @@ class Intrinsic<list<LLVMType> ret_types,
list<LLVMType> ParamTypes = param_types;
list<IntrinsicProperty> IntrProperties = intr_properties;
let Properties = sd_properties;
bit DisableDefaultAttributes = 1;


bit isTarget = 0;
}
Expand Down
6 changes: 5 additions & 1 deletion llvm/test/TableGen/intrinsic-long-name.td
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// RUN: llvm-tblgen -gen-intrinsic-enums %s | FileCheck %s
// XFAIL: vg_leak

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

class SDNodeProperty;

class ValueType<int size, int value> {
Expand All @@ -22,6 +25,7 @@ class Intrinsic<string name, list<LLVMType> param_types = []> {
list<LLVMType> ParamTypes = param_types;
list<IntrinsicProperty> IntrProperties = [];
list<SDNodeProperty> Properties = [];
bit DisableDefaultAttributes = 1;
}

def iAny : ValueType<0, 253>;
Expand Down
6 changes: 5 additions & 1 deletion llvm/test/TableGen/intrinsic-pointer-to-any.td
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
// case, so TableGen would hit an assertion in EncodeFixedType that was checking
// to ensure that the substitution being processed was correctly replaced.

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

class SDNodeProperty;

class ValueType<int size, int value> {
Expand All @@ -32,6 +35,7 @@ class Intrinsic<list<LLVMType> ret_types> {
list<IntrinsicProperty> IntrProperties = [];
list<SDNodeProperty> Properties = [];
bit isTarget = 0;
bit DisableDefaultAttributes = 1;
}

class LLVMQualPointerType<LLVMType elty>
Expand Down
6 changes: 5 additions & 1 deletion llvm/test/TableGen/intrinsic-struct.td
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// RUN: llvm-tblgen -gen-intrinsic-enums %s | FileCheck %s
// XFAIL: vg_leak

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

class SDNodeProperty;

class ValueType<int size, int value> {
Expand All @@ -22,6 +25,7 @@ class Intrinsic<string name, list<LLVMType> ret_types = []> {
list<LLVMType> ParamTypes = [];
list<IntrinsicProperty> IntrProperties = [];
list<SDNodeProperty> Properties = [];
bit DisableDefaultAttributes = 1;
}

def iAny : ValueType<0, 253>;
Expand Down
5 changes: 4 additions & 1 deletion llvm/test/TableGen/intrinsic-varargs.td
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

include "llvm/CodeGen/ValueTypes.td"

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}
class SDNodeProperty;

class LLVMType<ValueType vt> {
Expand All @@ -18,6 +20,7 @@ class Intrinsic<string name, list<LLVMType> param_types = []> {
list<LLVMType> ParamTypes = param_types;
list<IntrinsicProperty> IntrProperties = [];
list<SDNodeProperty> Properties = [];
bit DisableDefaultAttributes = 1;
}

def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
Expand Down
6 changes: 5 additions & 1 deletion llvm/test/TableGen/searchabletables-intrinsic.td
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

include "llvm/TableGen/SearchableTable.td"

class IntrinsicProperty;
class IntrinsicProperty<bit is_default = 0> {
bit IsDefault = is_default;
}

class SDNodeProperty;

class ValueType<int size, int value> {
Expand All @@ -24,6 +27,7 @@ class Intrinsic<list<LLVMType> param_types = []> {
list<LLVMType> ParamTypes = param_types;
list<IntrinsicProperty> IntrProperties = [];
list<SDNodeProperty> Properties = [];
bit DisableDefaultAttributes = 1;
}

def iAny : ValueType<0, 253>;
Expand Down
9 changes: 8 additions & 1 deletion llvm/utils/TableGen/CodeGenIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ struct CodeGenIntrinsic {
return Properties & (1 << Prop);
}

/// Goes through all IntrProperties that have IsDefault
/// value set and sets the property.
void setDefaultProperties(Record *R, std::vector<Record *> DefaultProperties);

/// Helper function to set property \p Name to true;
void setProperty(Record *R);

/// Returns true if the parameter at \p ParamIdx is a pointer type. Returns
/// false if the parameter is not a pointer, or \p ParamIdx is greater than
/// the size of \p IS.ParamVTs.
Expand All @@ -185,7 +192,7 @@ struct CodeGenIntrinsic {

bool isParamImmArg(unsigned ParamIdx) const;

CodeGenIntrinsic(Record *R);
CodeGenIntrinsic(Record *R, std::vector<Record *> DefaultProperties);
};

class CodeGenIntrinsicTable {
Expand Down
155 changes: 90 additions & 65 deletions llvm/utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,19 @@ ComplexPattern::ComplexPattern(Record *R) {
//===----------------------------------------------------------------------===//

CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
std::vector<Record*> Defs = RC.getAllDerivedDefinitions("Intrinsic");
std::vector<Record *> IntrProperties =
RC.getAllDerivedDefinitions("IntrinsicProperty");

std::vector<Record *> DefaultProperties;
for (Record *Rec : IntrProperties)
if (Rec->getValueAsBit("IsDefault"))
DefaultProperties.push_back(Rec);

std::vector<Record *> Defs = RC.getAllDerivedDefinitions("Intrinsic");
Intrinsics.reserve(Defs.size());

for (unsigned I = 0, e = Defs.size(); I != e; ++I)
Intrinsics.push_back(CodeGenIntrinsic(Defs[I]));
Intrinsics.push_back(CodeGenIntrinsic(Defs[I], DefaultProperties));

llvm::sort(Intrinsics,
[](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
Expand All @@ -620,7 +627,8 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
}

CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
std::vector<Record *> DefaultProperties) {
TheDef = R;
std::string DefName = std::string(R->getName());
ArrayRef<SMLoc> DefLoc = R->getLoc();
Expand Down Expand Up @@ -766,75 +774,17 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
IS.ParamTypeDefs.push_back(TyEl);
}

// Set default properties to true.
setDefaultProperties(R, DefaultProperties);

// Parse the intrinsic properties.
ListInit *PropList = R->getValueAsListInit("IntrProperties");
for (unsigned i = 0, e = PropList->size(); i != e; ++i) {
Record *Property = PropList->getElementAsRecord(i);
assert(Property->isSubClassOf("IntrinsicProperty") &&
"Expected a property!");

if (Property->getName() == "IntrNoMem")
ModRef = NoMem;
else if (Property->getName() == "IntrReadMem")
ModRef = ModRefBehavior(ModRef & ~MR_Mod);
else if (Property->getName() == "IntrWriteMem")
ModRef = ModRefBehavior(ModRef & ~MR_Ref);
else if (Property->getName() == "IntrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem);
else if (Property->getName() == "IntrInaccessibleMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_InaccessibleMem);
else if (Property->getName() == "IntrInaccessibleMemOrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem |
MR_InaccessibleMem);
else if (Property->getName() == "Commutative")
isCommutative = true;
else if (Property->getName() == "Throws")
canThrow = true;
else if (Property->getName() == "IntrNoDuplicate")
isNoDuplicate = true;
else if (Property->getName() == "IntrConvergent")
isConvergent = true;
else if (Property->getName() == "IntrNoReturn")
isNoReturn = true;
else if (Property->getName() == "IntrNoSync")
isNoSync = true;
else if (Property->getName() == "IntrNoFree")
isNoFree = true;
else if (Property->getName() == "IntrWillReturn")
isWillReturn = true;
else if (Property->getName() == "IntrCold")
isCold = true;
else if (Property->getName() == "IntrSpeculatable")
isSpeculatable = true;
else if (Property->getName() == "IntrHasSideEffects")
hasSideEffects = true;
else if (Property->isSubClassOf("NoCapture")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, NoCapture, 0);
} else if (Property->isSubClassOf("NoAlias")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, NoAlias, 0);
} else if (Property->isSubClassOf("Returned")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, Returned, 0);
} else if (Property->isSubClassOf("ReadOnly")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ReadOnly, 0);
} else if (Property->isSubClassOf("WriteOnly")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, WriteOnly, 0);
} else if (Property->isSubClassOf("ReadNone")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ReadNone, 0);
} else if (Property->isSubClassOf("ImmArg")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ImmArg, 0);
} else if (Property->isSubClassOf("Align")) {
unsigned ArgNo = Property->getValueAsInt("ArgNo");
uint64_t Align = Property->getValueAsInt("Align");
ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
} else
llvm_unreachable("Unknown property!");
setProperty(Property);
}

// Also record the SDPatternOperator Properties.
Expand All @@ -844,6 +794,81 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
llvm::sort(ArgumentAttributes);
}

void CodeGenIntrinsic::setDefaultProperties(
Record *R, std::vector<Record *> DefaultProperties) {
// opt-out of using default attributes.
if (R->getValueAsBit("DisableDefaultAttributes"))
return;

for (Record *Rec : DefaultProperties)
setProperty(Rec);
}

void CodeGenIntrinsic::setProperty(Record *R) {
if (R->getName() == "IntrNoMem")
ModRef = NoMem;
else if (R->getName() == "IntrReadMem")
ModRef = ModRefBehavior(ModRef & ~MR_Mod);
else if (R->getName() == "IntrWriteMem")
ModRef = ModRefBehavior(ModRef & ~MR_Ref);
else if (R->getName() == "IntrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem);
else if (R->getName() == "IntrInaccessibleMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_InaccessibleMem);
else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem |
MR_InaccessibleMem);
else if (R->getName() == "Commutative")
isCommutative = true;
else if (R->getName() == "Throws")
canThrow = true;
else if (R->getName() == "IntrNoDuplicate")
isNoDuplicate = true;
else if (R->getName() == "IntrConvergent")
isConvergent = true;
else if (R->getName() == "IntrNoReturn")
isNoReturn = true;
else if (R->getName() == "IntrNoSync")
isNoSync = true;
else if (R->getName() == "IntrNoFree")
isNoFree = true;
else if (R->getName() == "IntrWillReturn")
isWillReturn = true;
else if (R->getName() == "IntrCold")
isCold = true;
else if (R->getName() == "IntrSpeculatable")
isSpeculatable = true;
else if (R->getName() == "IntrHasSideEffects")
hasSideEffects = true;
else if (R->isSubClassOf("NoCapture")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, NoCapture, 0);
} else if (R->isSubClassOf("NoAlias")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, NoAlias, 0);
} else if (R->isSubClassOf("Returned")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, Returned, 0);
} else if (R->isSubClassOf("ReadOnly")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ReadOnly, 0);
} else if (R->isSubClassOf("WriteOnly")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, WriteOnly, 0);
} else if (R->isSubClassOf("ReadNone")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ReadNone, 0);
} else if (R->isSubClassOf("ImmArg")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
ArgumentAttributes.emplace_back(ArgNo, ImmArg, 0);
} else if (R->isSubClassOf("Align")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
uint64_t Align = R->getValueAsInt("Align");
ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
} else
llvm_unreachable("Unknown property!");
}

bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
if (ParamIdx >= IS.ParamVTs.size())
return false;
Expand Down
3 changes: 2 additions & 1 deletion llvm/utils/TableGen/SearchableTableEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ class SearchableTableEmitter {
CodeGenIntrinsic &getIntrinsic(Init *I) {
std::unique_ptr<CodeGenIntrinsic> &Intr = Intrinsics[I];
if (!Intr)
Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef());
Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef(),
std::vector<Record *>());
return *Intr;
}

Expand Down

0 comments on commit 99d18f7

Please sign in to comment.