Skip to content

Commit 05e6bb4

Browse files
authored
[SelectionDAG] Add an ISD::CLEAR_CACHE node to lower llvm.clear_cache (llvm#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.
1 parent 191e64f commit 05e6bb4

File tree

11 files changed

+51
-19
lines changed

11 files changed

+51
-19
lines changed

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,11 @@ enum NodeType {
14071407
// Output: Output Chain
14081408
EXPERIMENTAL_VECTOR_HISTOGRAM,
14091409

1410+
// llvm.clear_cache intrinsic
1411+
// Operands: Input Chain, Start Addres, End Address
1412+
// Outputs: Output Chain
1413+
CLEAR_CACHE,
1414+
14101415
/// BUILTIN_OP_END - This must be the last enum value in this list.
14111416
/// The target-specific pre-isel opcode values start here.
14121417
BUILTIN_OP_END

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4764,12 +4764,6 @@ class TargetLowering : public TargetLoweringBase {
47644764
return false;
47654765
}
47664766

4767-
/// Return the builtin name for the __builtin___clear_cache intrinsic
4768-
/// Default is to invoke the clear cache library call
4769-
virtual const char * getClearCacheBuiltinName() const {
4770-
return "__clear_cache";
4771-
}
4772-
47734767
/// Return the register ID of the name passed in. Used by named register
47744768
/// global variables extension. There is no target-independent behaviour
47754769
/// so the default action is to bail.

llvm/include/llvm/IR/RuntimeLibcalls.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,5 +616,8 @@ HANDLE_LIBCALL(DEOPTIMIZE, "__llvm_deoptimize")
616616
// Return address
617617
HANDLE_LIBCALL(RETURN_ADDRESS, nullptr)
618618

619+
// Clear cache
620+
HANDLE_LIBCALL(CLEAR_CACHE, "__clear_cache")
621+
619622
HANDLE_LIBCALL(UNKNOWN_LIBCALL, nullptr)
620623

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,11 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
11051105
if (Action == TargetLowering::Legal)
11061106
Action = TargetLowering::Custom;
11071107
break;
1108+
case ISD::CLEAR_CACHE:
1109+
// This operation is typically going to be LibCall unless the target wants
1110+
// something differrent.
1111+
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
1112+
break;
11081113
case ISD::READCYCLECOUNTER:
11091114
case ISD::READSTEADYCOUNTER:
11101115
// READCYCLECOUNTER and READSTEADYCOUNTER return a i64, even if type
@@ -4298,6 +4303,11 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
42984303
case ISD::VP_CTTZ_ELTS_ZERO_UNDEF:
42994304
Results.push_back(TLI.expandVPCTTZElements(Node, DAG));
43004305
break;
4306+
case ISD::CLEAR_CACHE:
4307+
// The default expansion of llvm.clear_cache is simply a no-op for those
4308+
// targets where it is not needed.
4309+
Results.push_back(Node->getOperand(0));
4310+
break;
43014311
case ISD::GLOBAL_OFFSET_TABLE:
43024312
case ISD::GlobalAddress:
43034313
case ISD::GlobalTLSAddress:
@@ -4455,6 +4465,17 @@ void SelectionDAGLegalize::ConvertNodeToLibcall(SDNode *Node) {
44554465
Results.push_back(CallResult.second);
44564466
break;
44574467
}
4468+
case ISD::CLEAR_CACHE: {
4469+
TargetLowering::MakeLibCallOptions CallOptions;
4470+
SDValue InputChain = Node->getOperand(0);
4471+
SDValue StartVal = Node->getOperand(1);
4472+
SDValue EndVal = Node->getOperand(2);
4473+
std::pair<SDValue, SDValue> Tmp = TLI.makeLibCall(
4474+
DAG, RTLIB::CLEAR_CACHE, MVT::isVoid, {StartVal, EndVal}, CallOptions,
4475+
SDLoc(Node), InputChain);
4476+
Results.push_back(Tmp.second);
4477+
break;
4478+
}
44584479
case ISD::FMINNUM:
44594480
case ISD::STRICT_FMINNUM:
44604481
ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7516,11 +7516,16 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
75167516
case Intrinsic::invariant_end:
75177517
// Discard region information.
75187518
return;
7519-
case Intrinsic::clear_cache:
7520-
/// FunctionName may be null.
7521-
if (const char *FunctionName = TLI.getClearCacheBuiltinName())
7522-
lowerCallToExternalSymbol(I, FunctionName);
7519+
case Intrinsic::clear_cache: {
7520+
SDValue InputChain = DAG.getRoot();
7521+
SDValue StartVal = getValue(I.getArgOperand(0));
7522+
SDValue EndVal = getValue(I.getArgOperand(1));
7523+
Res = DAG.getNode(ISD::CLEAR_CACHE, sdl, DAG.getVTList(MVT::Other),
7524+
{InputChain, StartVal, EndVal});
7525+
setValue(&I, Res);
7526+
DAG.setRoot(Res);
75237527
return;
7528+
}
75247529
case Intrinsic::donothing:
75257530
case Intrinsic::seh_try_begin:
75267531
case Intrinsic::seh_scope_begin:

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
528528
return "stackmap";
529529
case ISD::PATCHPOINT:
530530
return "patchpoint";
531+
case ISD::CLEAR_CACHE:
532+
return "clear_cache";
531533

532534
case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
533535
return "histogram";

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,10 @@ void TargetLoweringBase::initActions() {
10351035
setOperationAction(ISD::SET_FPMODE, VT, Expand);
10361036
}
10371037
setOperationAction(ISD::RESET_FPMODE, MVT::Other, Expand);
1038+
1039+
// This one by default will call __clear_cache unless the target
1040+
// wants something different.
1041+
setOperationAction(ISD::CLEAR_CACHE, MVT::Other, LibCall);
10381042
}
10391043

10401044
MVT TargetLoweringBase::getScalarShiftAmountTy(const DataLayout &DL,

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
111111
setOperationAction(ISD::JumpTable, MVTPtr, Custom);
112112
setOperationAction(ISD::BlockAddress, MVTPtr, Custom);
113113
setOperationAction(ISD::BRIND, MVT::Other, Custom);
114+
setOperationAction(ISD::CLEAR_CACHE, MVT::Other, Custom);
114115

115116
// Take the default expansion for va_arg, va_copy, and va_end. There is no
116117
// default action for va_start, so we do that custom.
@@ -1503,6 +1504,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
15031504
case ISD::CTLZ:
15041505
case ISD::CTTZ:
15051506
return DAG.UnrollVectorOp(Op.getNode());
1507+
case ISD::CLEAR_CACHE:
1508+
report_fatal_error("llvm.clear_cache is not supported on wasm");
15061509
}
15071510
}
15081511

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,6 @@ class WebAssemblyTargetLowering final : public TargetLowering {
111111
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
112112
SelectionDAG &DAG) const override;
113113

114-
const char *getClearCacheBuiltinName() const override {
115-
report_fatal_error("llvm.clear_cache is not supported on wasm");
116-
}
117-
118114
bool
119115
shouldSimplifyDemandedVectorElts(SDValue Op,
120116
const TargetLoweringOpt &TLO) const override;

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
136136
// X86-SSE is even stranger. It uses -1 or 0 for vector masks.
137137
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
138138

139+
// X86 instruction cache is coherent with its data cache so we can use the
140+
// default expansion to a no-op.
141+
setOperationAction(ISD::CLEAR_CACHE, MVT::Other, Expand);
142+
139143
// For 64-bit, since we have so many registers, use the ILP scheduler.
140144
// For 32-bit, use the register pressure specific scheduling.
141145
// For Atom, always use ILP scheduling.

llvm/lib/Target/X86/X86ISelLowering.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,11 +1473,6 @@ namespace llvm {
14731473
const SelectionDAG &DAG,
14741474
const MachineMemOperand &MMO) const override;
14751475

1476-
/// Intel processors have a unified instruction and data cache
1477-
const char * getClearCacheBuiltinName() const override {
1478-
return nullptr; // nothing to do, move along.
1479-
}
1480-
14811476
Register getRegisterByName(const char* RegName, LLT VT,
14821477
const MachineFunction &MF) const override;
14831478

0 commit comments

Comments
 (0)