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();
112#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
122 OS <<
"Uninitialized";
123 else if (isUnknown())
132#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
148 VXRMInfo AvailableIn;
151 VXRMInfo AvailableOut;
154 VXRMInfo AnticipatedIn;
157 VXRMInfo AnticipatedOut;
168 std::vector<BlockData> BlockInfo;
169 std::queue<const MachineBasicBlock *> WorkList;
196char RISCVInsertWriteVXRM::ID = 0;
205 case RISCV::VNCLIP_WI:
206 case RISCV::VNCLIPU_WI:
207 return MI.getOperand(3).getImm() == 0;
214 bool NeedVXRMWrite =
false;
217 if (VXRMIdx >= 0 && !ignoresVXRM(
MI)) {
218 unsigned NewVXRMImm =
MI.getOperand(VXRMIdx).getImm();
220 if (!BBInfo.VXRMUse.isValid())
221 BBInfo.VXRMUse.setVXRMImm(NewVXRMImm);
223 BBInfo.VXRMOut.setVXRMImm(NewVXRMImm);
224 NeedVXRMWrite =
true;
228 if (
MI.isCall() ||
MI.isInlineAsm() ||
229 MI.modifiesRegister(RISCV::VXRM,
nullptr)) {
230 if (!BBInfo.VXRMUse.isValid())
231 BBInfo.VXRMUse.setUnknown();
233 BBInfo.VXRMOut.setUnknown();
237 return NeedVXRMWrite;
243 BBInfo.InQueue =
false;
260 <<
" changed to " << BBInfo.AvailableIn <<
"\n");
263 if (BBInfo.VXRMOut.isValid())
271 <<
" changed to " << BBInfo.AvailableOut <<
"\n");
275 if (!BlockInfo[S->getNumber()].InQueue) {
276 BlockInfo[S->getNumber()].InQueue =
true;
285 BBInfo.InQueue =
false;
287 VXRMInfo Anticipated;
289 Anticipated.setUnknown();
293 Anticipated.intersect(BlockInfo[S->getNumber()].AnticipatedIn);
297 if (!Anticipated.isValid())
300 if (Anticipated != BBInfo.AnticipatedOut) {
301 BBInfo.AnticipatedOut = Anticipated;
303 <<
" changed to " << BBInfo.AnticipatedOut <<
"\n");
307 if (BBInfo.VXRMUse.isValid())
308 Anticipated = BBInfo.VXRMUse;
310 if (Anticipated == BBInfo.AnticipatedIn)
313 BBInfo.AnticipatedIn = Anticipated;
315 <<
" changed to " << BBInfo.AnticipatedIn <<
"\n");
319 if (!BlockInfo[
P->getNumber()].InQueue) {
320 BlockInfo[
P->getNumber()].InQueue =
true;
329 VXRMInfo
Info = BBInfo.AvailableIn;
333 bool PendingInsert =
false;
336 if (BBInfo.AnticipatedIn.isStatic()) {
339 PendingInsert =
true;
347 const BlockData &PInfo = BlockInfo[
P->getNumber()];
349 if (PInfo.AvailableOut.isStatic() &&
350 PInfo.AvailableOut.getVXRMImm() ==
351 BBInfo.AnticipatedIn.getVXRMImm())
356 if (PInfo.AnticipatedOut.isStatic() &&
357 PInfo.AnticipatedOut.getVXRMImm() ==
358 BBInfo.AnticipatedIn.getVXRMImm())
360 PendingInsert =
true;
365 Info = BBInfo.AnticipatedIn;
370 if (VXRMIdx >= 0 && !ignoresVXRM(
MI)) {
371 unsigned NewVXRMImm =
MI.getOperand(VXRMIdx).getImm();
373 if (PendingInsert || !
Info.isStatic() ||
374 Info.getVXRMImm() != NewVXRMImm) {
376 (
Info.isStatic() &&
Info.getVXRMImm() == NewVXRMImm)) &&
377 "Pending VXRM insertion mismatch");
381 PendingInsert =
false;
386 Info.setVXRMImm(NewVXRMImm);
390 if (
MI.isCall() ||
MI.isInlineAsm() ||
391 MI.modifiesRegister(RISCV::VXRM,
nullptr))
401 (BBInfo.AnticipatedOut.isStatic() &&
403 Info.getVXRMImm() != BBInfo.AnticipatedOut.getVXRMImm()))) {
405 (
Info.isStatic() && BBInfo.AnticipatedOut.isStatic() &&
406 Info.getVXRMImm() == BBInfo.AnticipatedOut.getVXRMImm())) &&
407 "Pending VXRM insertion mismatch");
409 <<
" changing to " << BBInfo.AnticipatedOut <<
"\n");
411 TII->get(RISCV::WriteVXRMImm))
412 .
addImm(BBInfo.AnticipatedOut.getVXRMImm());
419 if (!
ST.hasVInstructions())
422 TII =
ST.getInstrInfo();
424 assert(BlockInfo.empty() &&
"Expect empty block infos");
428 bool NeedVXRMChange =
false;
430 NeedVXRMChange |= computeVXRMChanges(
MBB);
432 if (!NeedVXRMChange) {
442 while (!WorkList.empty()) {
445 computeAvailable(
MBB);
453 while (!WorkList.empty()) {
456 computeAnticipated(
MBB);
469 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 ValueLatticeElement intersect(const ValueLatticeElement &A, const ValueLatticeElement &B)
Combine two sets of facts about the same value into a single set of facts.
#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.