36#define DEBUG_TYPE "riscv-insert-write-vxrm"
37#define RISCV_INSERT_WRITE_VXRM_NAME "RISC-V Insert Write VXRM Pass"
53 static VXRMInfo getUnknown() {
60 void setUnknown() { State = Unknown; }
61 bool isUnknown()
const {
return State == Unknown; }
63 bool isStatic()
const {
return State == Static; }
65 void setVXRMImm(
unsigned Imm) {
66 assert(Imm <= 3 &&
"Unexpected VXRM value");
70 unsigned getVXRMImm()
const {
71 assert(isStatic() && VXRMImm <= 3 &&
"Unexpected state");
77 if (State !=
Other.State)
81 return VXRMImm ==
Other.VXRMImm;
101 if (isUnknown() ||
Other.isUnknown())
102 return VXRMInfo::getUnknown();
109 return VXRMInfo::getUnknown();
118 VXRMInfo intersectAnticipated(
const VXRMInfo &
Other)
const {
120 if (!
Other.isValid())
130 if (
Other.isUnknown())
138 return VXRMInfo::getUnknown();
141#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
151 OS <<
"Uninitialized";
152 else if (isUnknown())
161#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
177 VXRMInfo AvailableIn;
180 VXRMInfo AvailableOut;
183 VXRMInfo AnticipatedIn;
186 VXRMInfo AnticipatedOut;
197 std::vector<BlockData> BlockInfo;
198 std::queue<const MachineBasicBlock *> WorkList;
225char RISCVInsertWriteVXRM::ID = 0;
234 case RISCV::VNCLIP_WI:
235 case RISCV::VNCLIPU_WI:
236 return MI.getOperand(3).getImm() == 0;
243 bool NeedVXRMWrite =
false;
246 if (VXRMIdx >= 0 && !ignoresVXRM(
MI)) {
247 unsigned NewVXRMImm =
MI.getOperand(VXRMIdx).getImm();
249 if (!BBInfo.VXRMUse.isValid())
250 BBInfo.VXRMUse.setVXRMImm(NewVXRMImm);
252 BBInfo.VXRMOut.setVXRMImm(NewVXRMImm);
253 NeedVXRMWrite =
true;
257 if (
MI.isCall() ||
MI.isInlineAsm() ||
258 MI.modifiesRegister(RISCV::VXRM,
nullptr)) {
259 if (!BBInfo.VXRMUse.isValid())
260 BBInfo.VXRMUse.setUnknown();
262 BBInfo.VXRMOut.setUnknown();
266 return NeedVXRMWrite;
272 BBInfo.InQueue =
false;
289 <<
" changed to " << BBInfo.AvailableIn <<
"\n");
292 if (BBInfo.VXRMOut.isValid())
300 <<
" changed to " << BBInfo.AvailableOut <<
"\n");
304 if (!BlockInfo[S->getNumber()].InQueue) {
305 BlockInfo[S->getNumber()].InQueue =
true;
315 BBInfo.InQueue =
false;
317 VXRMInfo Anticipated;
319 Anticipated.setUnknown();
322 if (
ST.hasVXRMPipelineFlush())
324 Anticipated.intersectAnticipated(BlockInfo[S->getNumber()].AnticipatedIn);
327 Anticipated.intersect(BlockInfo[S->getNumber()].AnticipatedIn);
331 if (!Anticipated.isValid())
334 if (Anticipated != BBInfo.AnticipatedOut) {
335 BBInfo.AnticipatedOut = Anticipated;
337 <<
" changed to " << BBInfo.AnticipatedOut <<
"\n");
341 if (BBInfo.VXRMUse.isValid())
342 Anticipated = BBInfo.VXRMUse;
344 if (Anticipated == BBInfo.AnticipatedIn)
347 BBInfo.AnticipatedIn = Anticipated;
349 <<
" changed to " << BBInfo.AnticipatedIn <<
"\n");
353 if (!BlockInfo[
P->getNumber()].InQueue) {
354 BlockInfo[
P->getNumber()].InQueue =
true;
363 VXRMInfo
Info = BBInfo.AvailableIn;
367 bool PendingInsert =
false;
370 if (BBInfo.AnticipatedIn.isStatic()) {
373 PendingInsert =
true;
381 const BlockData &PInfo = BlockInfo[
P->getNumber()];
383 if (PInfo.AvailableOut.isStatic() &&
384 PInfo.AvailableOut.getVXRMImm() ==
385 BBInfo.AnticipatedIn.getVXRMImm())
390 if (PInfo.AnticipatedOut.isStatic() &&
391 PInfo.AnticipatedOut.getVXRMImm() ==
392 BBInfo.AnticipatedIn.getVXRMImm())
394 PendingInsert =
true;
399 Info = BBInfo.AnticipatedIn;
404 if (VXRMIdx >= 0 && !ignoresVXRM(
MI)) {
405 unsigned NewVXRMImm =
MI.getOperand(VXRMIdx).getImm();
407 if (PendingInsert || !
Info.isStatic() ||
408 Info.getVXRMImm() != NewVXRMImm) {
410 (
Info.isStatic() &&
Info.getVXRMImm() == NewVXRMImm)) &&
411 "Pending VXRM insertion mismatch");
415 PendingInsert =
false;
420 Info.setVXRMImm(NewVXRMImm);
424 if (
MI.isCall() ||
MI.isInlineAsm() ||
425 MI.modifiesRegister(RISCV::VXRM,
nullptr))
435 (BBInfo.AnticipatedOut.isStatic() &&
437 Info.getVXRMImm() != BBInfo.AnticipatedOut.getVXRMImm()))) {
439 (
Info.isStatic() && BBInfo.AnticipatedOut.isStatic() &&
440 Info.getVXRMImm() == BBInfo.AnticipatedOut.getVXRMImm())) &&
441 "Pending VXRM insertion mismatch");
443 <<
" changing to " << BBInfo.AnticipatedOut <<
"\n");
445 TII->get(RISCV::WriteVXRMImm))
446 .
addImm(BBInfo.AnticipatedOut.getVXRMImm());
453 if (!
ST.hasVInstructions())
456 TII =
ST.getInstrInfo();
458 assert(BlockInfo.empty() &&
"Expect empty block infos");
462 bool NeedVXRMChange =
false;
464 NeedVXRMChange |= computeVXRMChanges(
MBB);
466 if (!NeedVXRMChange) {
476 while (!WorkList.empty()) {
479 computeAvailable(
MBB);
487 while (!WorkList.empty()) {
490 computeAnticipated(MF,
MBB);
503 return new RISCVInsertWriteVXRM();
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Analysis containing CSE Info
#define LLVM_ATTRIBUTE_USED
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
std::optional< std::vector< StOtherPiece > > Other
@ Available
We know the block is fully available. This is a fixpoint.
const HexagonInstrInfo * TII
static Interval intersect(const Interval &I1, const Interval &I2)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define RISCV_INSERT_WRITE_VXRM_NAME
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool isEntryBlock() const
Returns true if this is the entry block of the function.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static int getVXRMOpNum(const MCInstrDesc &Desc)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool operator!=(uint64_t V1, const APInt &V2)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
FunctionPass * createRISCVInsertWriteVXRMPass()
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.