[llvm] 05e6bb4 - [SelectionDAG] Add an ISD::CLEAR_CACHE node to lower llvm.clear_cache (#93795)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 30 05:55:35 PDT 2024
Author: Roger Ferrer Ibáñez
Date: 2024-05-30T14:55:32+02:00
New Revision: 05e6bb40ebfd285cc87f7ce326b7ba76c3c7f870
URL: https://github.com/llvm/llvm-project/commit/05e6bb40ebfd285cc87f7ce326b7ba76c3c7f870
DIFF: https://github.com/llvm/llvm-project/commit/05e6bb40ebfd285cc87f7ce326b7ba76c3c7f870.diff
LOG: [SelectionDAG] Add an ISD::CLEAR_CACHE node to lower llvm.clear_cache (#93795)
The current way of lowering `llvm.clear_cache` is a bit unusual. As
suggested by Matt Arsenault we are better off using an ISD node.
This change introduces a new `ISD::CLEAR_CACHE`, registers a new libcall
by default named `__clear_cache` and the default legalisation is a
libcall.
This is preparatory work for a custom lowering of `ISD::CLEAR_CACHE`
needed by RISC-V on some platforms.
Added:
Modified:
llvm/include/llvm/CodeGen/ISDOpcodes.h
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/include/llvm/IR/RuntimeLibcalls.def
llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
llvm/lib/CodeGen/TargetLoweringBase.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/lib/Target/X86/X86ISelLowering.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index d8af97957e48e..0f87e062e2da6 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1407,6 +1407,11 @@ enum NodeType {
// Output: Output Chain
EXPERIMENTAL_VECTOR_HISTOGRAM,
+ // llvm.clear_cache intrinsic
+ // Operands: Input Chain, Start Addres, End Address
+ // Outputs: Output Chain
+ CLEAR_CACHE,
+
/// BUILTIN_OP_END - This must be the last enum value in this list.
/// The target-specific pre-isel opcode values start here.
BUILTIN_OP_END
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 50a8c7eb75af5..2765caec960c9 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4764,12 +4764,6 @@ class TargetLowering : public TargetLoweringBase {
return false;
}
- /// Return the builtin name for the __builtin___clear_cache intrinsic
- /// Default is to invoke the clear cache library call
- virtual const char * getClearCacheBuiltinName() const {
- return "__clear_cache";
- }
-
/// Return the register ID of the name passed in. Used by named register
/// global variables extension. There is no target-independent behaviour
/// so the default action is to bail.
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def
index 5e082769fa974..a5a72884a6bf5 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -616,5 +616,8 @@ HANDLE_LIBCALL(DEOPTIMIZE, "__llvm_deoptimize")
// Return address
HANDLE_LIBCALL(RETURN_ADDRESS, nullptr)
+// Clear cache
+HANDLE_LIBCALL(CLEAR_CACHE, "__clear_cache")
+
HANDLE_LIBCALL(UNKNOWN_LIBCALL, nullptr)
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 51f2cf9017f85..8cd2bb60d81f2 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1105,6 +1105,11 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
if (Action == TargetLowering::Legal)
Action = TargetLowering::Custom;
break;
+ case ISD::CLEAR_CACHE:
+ // This operation is typically going to be LibCall unless the target wants
+ // something
diff errent.
+ Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
+ break;
case ISD::READCYCLECOUNTER:
case ISD::READSTEADYCOUNTER:
// READCYCLECOUNTER and READSTEADYCOUNTER return a i64, even if type
@@ -4298,6 +4303,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
Results.push_back(TLI.expandVPCTTZElements(Node, DAG));
break;
+ case ISD::CLEAR_CACHE:
+ // The default expansion of llvm.clear_cache is simply a no-op for those
+ // targets where it is not needed.
+ Results.push_back(Node->getOperand(0));
+ break;
case ISD::GLOBAL_OFFSET_TABLE:
case ISD::GlobalAddress:
case ISD::GlobalTLSAddress:
@@ -4455,6 +4465,17 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
Results.push_back(CallResult.second);
break;
}
+ case ISD::CLEAR_CACHE: {
+ TargetLowering::MakeLibCallOptions CallOptions;
+ SDValue InputChain = Node->getOperand(0);
+ SDValue StartVal = Node->getOperand(1);
+ SDValue EndVal = Node->getOperand(2);
+ std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
+ DAG, RTLIB::CLEAR_CACHE, MVT::isVoid, {StartVal, EndVal}, CallOptions,
+ SDLoc(Node), InputChain);
+ Results.push_back(Tmp.second);
+ break;
+ }
case ISD::FMINNUM:
case ISD::STRICT_FMINNUM:
ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index ca352da5d36eb..85e4cc3b82e6e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -7516,11 +7516,16 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
case Intrinsic::invariant_end:
// Discard region information.
return;
- case Intrinsic::clear_cache:
- /// FunctionName may be null.
- if (const char *FunctionName = TLI.getClearCacheBuiltinName())
- lowerCallToExternalSymbol(I, FunctionName);
+ case Intrinsic::clear_cache: {
+ SDValue InputChain = DAG.getRoot();
+ SDValue StartVal = getValue(I.getArgOperand(0));
+ SDValue EndVal = getValue(I.getArgOperand(1));
+ Res = DAG.getNode(ISD::CLEAR_CACHE, sdl, DAG.getVTList(MVT::Other),
+ {InputChain, StartVal, EndVal});
+ setValue(&I, Res);
+ DAG.setRoot(Res);
return;
+ }
case Intrinsic::donothing:
case Intrinsic::seh_try_begin:
case Intrinsic::seh_scope_begin:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 59742e90c6791..2198c2354483c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -528,6 +528,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
return "stackmap";
case ISD::PATCHPOINT:
return "patchpoint";
+ case ISD::CLEAR_CACHE:
+ return "clear_cache";
case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
return "histogram";
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index f2e4632b248f4..3aec7049e0cc8 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1035,6 +1035,10 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::SET_FPMODE, VT, Expand);
}
setOperationAction(ISD::RESET_FPMODE, MVT::Other, Expand);
+
+ // This one by default will call __clear_cache unless the target
+ // wants something
diff erent.
+ setOperationAction(ISD::CLEAR_CACHE, MVT::Other, LibCall);
}
MVT TargetLoweringBase::getScalarShiftAmountTy(const DataLayout &DL,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index 4beab9d091581..a793e59c3d1a7 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -111,6 +111,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
setOperationAction(ISD::JumpTable, MVTPtr, Custom);
setOperationAction(ISD::BlockAddress, MVTPtr, Custom);
setOperationAction(ISD::BRIND, MVT::Other, Custom);
+ setOperationAction(ISD::CLEAR_CACHE, MVT::Other, Custom);
// Take the default expansion for va_arg, va_copy, and va_end. There is no
// default action for va_start, so we do that custom.
@@ -1503,6 +1504,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
case ISD::CTLZ:
case ISD::CTTZ:
return DAG.UnrollVectorOp(Op.getNode());
+ case ISD::CLEAR_CACHE:
+ report_fatal_error("llvm.clear_cache is not supported on wasm");
}
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index 1d1338ab40d0e..7d9cfb7739e43 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -111,10 +111,6 @@ class WebAssemblyTargetLowering final : public TargetLowering {
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;
- const char *getClearCacheBuiltinName() const override {
- report_fatal_error("llvm.clear_cache is not supported on wasm");
- }
-
bool
shouldSimplifyDemandedVectorElts(SDValue Op,
const TargetLoweringOpt &TLO) const override;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f5d0e1b15d7a3..839006cbaed4c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -136,6 +136,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
// X86-SSE is even stranger. It uses -1 or 0 for vector masks.
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
+ // X86 instruction cache is coherent with its data cache so we can use the
+ // default expansion to a no-op.
+ setOperationAction(ISD::CLEAR_CACHE, MVT::Other, Expand);
+
// For 64-bit, since we have so many registers, use the ILP scheduler.
// For 32-bit, use the register pressure specific scheduling.
// For Atom, always use ILP scheduling.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index b0efa074b1978..3c5c903bc0d98 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1473,11 +1473,6 @@ namespace llvm {
const SelectionDAG &DAG,
const MachineMemOperand &MMO) const override;
- /// Intel processors have a unified instruction and data cache
- const char * getClearCacheBuiltinName() const override {
- return nullptr; // nothing to do, move along.
- }
-
Register getRegisterByName(const char* RegName, LLT VT,
const MachineFunction &MF) const override;
More information about the llvm-commits
mailing list