[llvm] r319475 - [globalisel][tablegen] Add support for relative AtomicOrderings
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 13:05:59 PST 2017
Author: dsanders
Date: Thu Nov 30 13:05:59 2017
New Revision: 319475
URL: http://llvm.org/viewvc/llvm-project?rev=319475&view=rev
Log:
[globalisel][tablegen] Add support for relative AtomicOrderings
No test yet because the relevant rules are blocked on the atomic_load,
and atomic_store nodes.
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
llvm/trunk/lib/Target/AArch64/AArch64InstrAtomics.td
llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Thu Nov 30 13:05:59 2017
@@ -115,6 +115,8 @@ enum {
/// - InsnID - Instruction ID
/// - Ordering - The AtomicOrdering value
GIM_CheckAtomicOrdering,
+ GIM_CheckAtomicOrderingOrStrongerThan,
+ GIM_CheckAtomicOrderingWeakerThan,
/// Check the type for the specified operand
/// - InsnID - Instruction ID
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h Thu Nov 30 13:05:59 2017
@@ -244,6 +244,44 @@ bool InstructionSelector::executeMatchTa
return false;
break;
}
+ case GIM_CheckAtomicOrderingOrStrongerThan: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
+ DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
+ dbgs() << CurrentIdx
+ << ": GIM_CheckAtomicOrderingOrStrongerThan(MIs["
+ << InsnID << "], " << (uint64_t)Ordering << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+
+ if (!State.MIs[InsnID]->hasOneMemOperand())
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+
+ for (const auto &MMO : State.MIs[InsnID]->memoperands())
+ if (!isAtLeastOrStrongerThan(MMO->getOrdering(), Ordering))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
+ case GIM_CheckAtomicOrderingWeakerThan: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ AtomicOrdering Ordering = (AtomicOrdering)MatchTable[CurrentIdx++];
+ DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
+ dbgs() << CurrentIdx
+ << ": GIM_CheckAtomicOrderingWeakerThan(MIs["
+ << InsnID << "], " << (uint64_t)Ordering << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+
+ if (!State.MIs[InsnID]->hasOneMemOperand())
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+
+ for (const auto &MMO : State.MIs[InsnID]->memoperands())
+ if (!isStrongerThan(Ordering, MMO->getOrdering()))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
case GIM_CheckType: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t OpIdx = MatchTable[CurrentIdx++];
Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAG.td?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSelectionDAG.td Thu Nov 30 13:05:59 2017
@@ -689,6 +689,14 @@ class PatFrag<dag ops, dag frag, code pr
// cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent
bit IsAtomicOrderingSequentiallyConsistent = ?;
+ // isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())
+ // !isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())
+ bit IsAtomicOrderingAcquireOrStronger = ?;
+
+ // isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())
+ // !isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())
+ bit IsAtomicOrderingReleaseOrStronger = ?;
+
// cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>;
// cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>;
ValueType MemoryVT = ?;
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrAtomics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrAtomics.td?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrAtomics.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrAtomics.td Thu Nov 30 13:05:59 2017
@@ -30,18 +30,18 @@ def : Pat<(atomic_fence (imm), (imm)), (
// A atomic load operation that actually needs acquire semantics.
class acquiring_load<PatFrag base>
- : PatFrag<(ops node:$ptr), (base node:$ptr), [{
- AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
- return isAcquireOrStronger(Ordering);
-}]>;
+ : PatFrag<(ops node:$ptr), (base node:$ptr)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquireOrStronger = 1;
+}
// An atomic load operation that does not need either acquire or release
// semantics.
class relaxed_load<PatFrag base>
- : PatFrag<(ops node:$ptr), (base node:$ptr), [{
- AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
- return !isAcquireOrStronger(Ordering);
-}]>;
+ : PatFrag<(ops node:$ptr), (base node:$ptr)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingAcquireOrStronger = 0;
+}
// 8-bit loads
def : Pat<(acquiring_load<atomic_load_8> GPR64sp:$ptr), (LDARB GPR64sp:$ptr)>;
@@ -113,19 +113,17 @@ def : Pat<(relaxed_load<atomic_load_64>
// A store operation that actually needs release semantics.
class releasing_store<PatFrag base>
- : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
- AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
- assert(Ordering != AtomicOrdering::AcquireRelease &&
- "unexpected store ordering");
- return isReleaseOrStronger(Ordering);
-}]>;
+ : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingReleaseOrStronger = 1;
+}
// An atomic store operation that doesn't actually need to be atomic on AArch64.
class relaxed_store<PatFrag base>
- : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{
- AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering();
- return !isReleaseOrStronger(Ordering);
-}]>;
+ : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val)> {
+ let IsAtomic = 1;
+ let IsAtomicOrderingReleaseOrStronger = 0;
+}
// 8-bit stores
def : Pat<(releasing_store<atomic_store_8> GPR64sp:$ptr, GPR32:$val),
Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp Thu Nov 30 13:05:59 2017
@@ -888,7 +888,11 @@ std::string TreePredicateFn::getPredCode
if (getMemoryVT() == nullptr && !isAtomicOrderingMonotonic() &&
!isAtomicOrderingAcquire() && !isAtomicOrderingRelease() &&
!isAtomicOrderingAcquireRelease() &&
- !isAtomicOrderingSequentiallyConsistent())
+ !isAtomicOrderingSequentiallyConsistent() &&
+ !isAtomicOrderingAcquireOrStronger() &&
+ !isAtomicOrderingReleaseOrStronger() &&
+ !isAtomicOrderingWeakerThanAcquire() &&
+ !isAtomicOrderingWeakerThanRelease())
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
"IsAtomic cannot be used by itself");
} else {
@@ -907,6 +911,15 @@ std::string TreePredicateFn::getPredCode
if (isAtomicOrderingSequentiallyConsistent())
PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
"IsAtomicOrderingSequentiallyConsistent requires IsAtomic");
+ if (isAtomicOrderingAcquireOrStronger())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingAcquireOrStronger requires IsAtomic");
+ if (isAtomicOrderingReleaseOrStronger())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingReleaseOrStronger requires IsAtomic");
+ if (isAtomicOrderingWeakerThanAcquire())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ "IsAtomicOrderingWeakerThanAcquire requires IsAtomic");
}
if (isLoad() || isStore() || isAtomic()) {
@@ -937,6 +950,20 @@ std::string TreePredicateFn::getPredCode
Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
"AtomicOrdering::SequentiallyConsistent) return false;\n";
+ if (isAtomic() && isAtomicOrderingAcquireOrStronger())
+ Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ "return false;\n";
+ if (isAtomic() && isAtomicOrderingWeakerThanAcquire())
+ Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ "return false;\n";
+
+ if (isAtomic() && isAtomicOrderingReleaseOrStronger())
+ Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ "return false;\n";
+ if (isAtomic() && isAtomicOrderingWeakerThanRelease())
+ Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ "return false;\n";
+
if (isLoad() || isStore()) {
StringRef SDNodeName = isLoad() ? "LoadSDNode" : "StoreSDNode";
@@ -1070,6 +1097,18 @@ bool TreePredicateFn::isAtomicOrderingSe
return isPredefinedPredicateEqualTo("IsAtomicOrderingSequentiallyConsistent",
true);
}
+bool TreePredicateFn::isAtomicOrderingAcquireOrStronger() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", true);
+}
+bool TreePredicateFn::isAtomicOrderingWeakerThanAcquire() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingAcquireOrStronger", false);
+}
+bool TreePredicateFn::isAtomicOrderingReleaseOrStronger() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", true);
+}
+bool TreePredicateFn::isAtomicOrderingWeakerThanRelease() const {
+ return isPredefinedPredicateEqualTo("IsAtomicOrderingReleaseOrStronger", false);
+}
Record *TreePredicateFn::getMemoryVT() const {
Record *R = getOrigPatFragRecord()->getRecord();
if (R->isValueUnset("MemoryVT"))
Modified: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.h Thu Nov 30 13:05:59 2017
@@ -516,6 +516,16 @@ public:
/// Is this predicate the predefined sequentially consistent atomic predicate?
bool isAtomicOrderingSequentiallyConsistent() const;
+ /// Is this predicate the predefined acquire-or-stronger atomic predicate?
+ bool isAtomicOrderingAcquireOrStronger() const;
+ /// Is this predicate the predefined weaker-than-acquire atomic predicate?
+ bool isAtomicOrderingWeakerThanAcquire() const;
+
+ /// Is this predicate the predefined release-or-stronger atomic predicate?
+ bool isAtomicOrderingReleaseOrStronger() const;
+ /// Is this predicate the predefined weaker-than-release atomic predicate?
+ bool isAtomicOrderingWeakerThanRelease() const;
+
/// If non-null, indicates that this predicate is a predefined memory VT
/// predicate for a load/store and returns the ValueType record for the memory VT.
Record *getMemoryVT() const;
Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=319475&r1=319474&r2=319475&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Thu Nov 30 13:05:59 2017
@@ -230,6 +230,14 @@ static std::string explainPredicates(con
Explanation += " acq_rel";
if (P.isAtomicOrderingSequentiallyConsistent())
Explanation += " seq_cst";
+ if (P.isAtomicOrderingAcquireOrStronger())
+ Explanation += " >=acquire";
+ if (P.isAtomicOrderingWeakerThanAcquire())
+ Explanation += " <acquire";
+ if (P.isAtomicOrderingReleaseOrStronger())
+ Explanation += " >=release";
+ if (P.isAtomicOrderingWeakerThanRelease())
+ Explanation += " <release";
}
return Explanation;
}
@@ -285,7 +293,11 @@ static Error isTrivialOperatorNode(const
Predicate.isAtomicOrderingAcquire() ||
Predicate.isAtomicOrderingRelease() ||
Predicate.isAtomicOrderingAcquireRelease() ||
- Predicate.isAtomicOrderingSequentiallyConsistent()))
+ Predicate.isAtomicOrderingSequentiallyConsistent() ||
+ Predicate.isAtomicOrderingAcquireOrStronger() ||
+ Predicate.isAtomicOrderingWeakerThanAcquire() ||
+ Predicate.isAtomicOrderingReleaseOrStronger() ||
+ Predicate.isAtomicOrderingWeakerThanRelease()))
continue;
HasUnsupportedPredicate = true;
@@ -1327,11 +1339,22 @@ public:
/// Generates code to check that a memory instruction has a atomic ordering
/// MachineMemoryOperand.
class AtomicOrderingMMOPredicateMatcher : public InstructionPredicateMatcher {
+public:
+ enum AOComparator {
+ AO_Exactly,
+ AO_OrStronger,
+ AO_WeakerThan,
+ };
+
+protected:
StringRef Order;
+ AOComparator Comparator;
public:
- AtomicOrderingMMOPredicateMatcher(StringRef Order)
- : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order) {}
+ AtomicOrderingMMOPredicateMatcher(StringRef Order,
+ AOComparator Comparator = AO_Exactly)
+ : InstructionPredicateMatcher(IPM_AtomicOrderingMMO), Order(Order),
+ Comparator(Comparator) {}
static bool classof(const InstructionPredicateMatcher *P) {
return P->getKind() == IPM_AtomicOrderingMMO;
@@ -1339,9 +1362,15 @@ public:
void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule,
unsigned InsnVarID) const override {
- Table << MatchTable::Opcode("GIM_CheckAtomicOrdering")
- << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
- << MatchTable::Comment("Order")
+ StringRef Opcode = "GIM_CheckAtomicOrdering";
+
+ if (Comparator == AO_OrStronger)
+ Opcode = "GIM_CheckAtomicOrderingOrStrongerThan";
+ if (Comparator == AO_WeakerThan)
+ Opcode = "GIM_CheckAtomicOrderingWeakerThan";
+
+ Table << MatchTable::Opcode(Opcode) << MatchTable::Comment("MI")
+ << MatchTable::IntValue(InsnVarID) << MatchTable::Comment("Order")
<< MatchTable::NamedValue(("(int64_t)AtomicOrdering::" + Order).str())
<< MatchTable::LineBreak;
}
@@ -2554,6 +2583,28 @@ Expected<InstructionMatcher &> GlobalISe
"SequentiallyConsistent");
continue;
}
+
+ if (Predicate.isAtomicOrderingAcquireOrStronger()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Acquire", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
+ continue;
+ }
+ if (Predicate.isAtomicOrderingWeakerThanAcquire()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Acquire", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
+ continue;
+ }
+
+ if (Predicate.isAtomicOrderingReleaseOrStronger()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Release", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
+ continue;
+ }
+ if (Predicate.isAtomicOrderingWeakerThanRelease()) {
+ InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
+ "Release", AtomicOrderingMMOPredicateMatcher::AO_WeakerThan);
+ continue;
+ }
}
return failedImport("Src pattern child has predicate (" +
More information about the llvm-commits
mailing list