Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
WebAssemblyRegStackify.cpp
Go to the documentation of this file.
1//===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements a register stacking pass.
11///
12/// This pass reorders instructions to put register uses and defs in an order
13/// such that they form single-use expression trees. Registers fitting this form
14/// are then marked as "stackified", meaning references to them are replaced by
15/// "push" and "pop" from the value stack.
16///
17/// This is primarily a code size optimization, since temporary values on the
18/// value stack don't need to be named.
19///
20//===----------------------------------------------------------------------===//
21
22#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"// for WebAssembly::ARGUMENT_*
23#include "WebAssembly.h"
24#include "WebAssemblyDebugValueManager.h"
25#include "WebAssemblyMachineFunctionInfo.h"
26#include "WebAssemblySubtarget.h"
27#include "WebAssemblyUtilities.h"
28#include "llvm/CodeGen/LiveIntervals.h"
29#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
30#include "llvm/CodeGen/MachineDominators.h"
31#include "llvm/CodeGen/MachineInstrBuilder.h"
32#include "llvm/CodeGen/MachineRegisterInfo.h"
33#include "llvm/CodeGen/Passes.h"
34#include "llvm/IR/GlobalAlias.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
37#include <iterator>
38using namespacellvm;
39
40#define DEBUG_TYPE "wasm-reg-stackify"
41
42namespace{
43classWebAssemblyRegStackify final :publicMachineFunctionPass {
44StringRefgetPassName() const override{
45return"WebAssembly Register Stackify";
46 }
47
48voidgetAnalysisUsage(AnalysisUsage &AU) const override{
49 AU.setPreservesCFG();
50 AU.addRequired<MachineDominatorTreeWrapperPass>();
51 AU.addRequired<LiveIntervalsWrapperPass>();
52 AU.addPreserved<MachineBlockFrequencyInfoWrapperPass>();
53 AU.addPreserved<SlotIndexesWrapperPass>();
54 AU.addPreserved<LiveIntervalsWrapperPass>();
55 AU.addPreservedID(LiveVariablesID);
56 AU.addPreserved<MachineDominatorTreeWrapperPass>();
57MachineFunctionPass::getAnalysisUsage(AU);
58 }
59
60boolrunOnMachineFunction(MachineFunction &MF)override;
61
62public:
63staticcharID;// Pass identification, replacement for typeid
64 WebAssemblyRegStackify() :MachineFunctionPass(ID) {}
65};
66}// end anonymous namespace
67
68char WebAssemblyRegStackify::ID = 0;
69INITIALIZE_PASS(WebAssemblyRegStackify,DEBUG_TYPE,
70"Reorder instructions to use the WebAssembly value stack",
71false,false)
72
73FunctionPass *llvm::createWebAssemblyRegStackify() {
74returnnew WebAssemblyRegStackify();
75}
76
77// Decorate the given instruction with implicit operands that enforce the
78// expression stack ordering constraints for an instruction which is on
79// the expression stack.
80staticvoidimposeStackOrdering(MachineInstr *MI) {
81// Write the opaque VALUE_STACK register.
82if (!MI->definesRegister(WebAssembly::VALUE_STACK,/*TRI=*/nullptr))
83MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
84/*isDef=*/true,
85/*isImp=*/true));
86
87// Also read the opaque VALUE_STACK register.
88if (!MI->readsRegister(WebAssembly::VALUE_STACK,/*TRI=*/nullptr))
89MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
90/*isDef=*/false,
91/*isImp=*/true));
92}
93
94// Convert an IMPLICIT_DEF instruction into an instruction which defines
95// a constant zero value.
96staticvoidconvertImplicitDefToConstZero(MachineInstr *MI,
97MachineRegisterInfo &MRI,
98constTargetInstrInfo *TII,
99MachineFunction &MF,
100LiveIntervals &LIS) {
101assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
102
103constauto *RegClass =MRI.getRegClass(MI->getOperand(0).getReg());
104if (RegClass == &WebAssembly::I32RegClass) {
105MI->setDesc(TII->get(WebAssembly::CONST_I32));
106MI->addOperand(MachineOperand::CreateImm(0));
107 }elseif (RegClass == &WebAssembly::I64RegClass) {
108MI->setDesc(TII->get(WebAssembly::CONST_I64));
109MI->addOperand(MachineOperand::CreateImm(0));
110 }elseif (RegClass == &WebAssembly::F32RegClass) {
111MI->setDesc(TII->get(WebAssembly::CONST_F32));
112auto *Val = cast<ConstantFP>(Constant::getNullValue(
113Type::getFloatTy(MF.getFunction().getContext())));
114MI->addOperand(MachineOperand::CreateFPImm(Val));
115 }elseif (RegClass == &WebAssembly::F64RegClass) {
116MI->setDesc(TII->get(WebAssembly::CONST_F64));
117auto *Val = cast<ConstantFP>(Constant::getNullValue(
118Type::getDoubleTy(MF.getFunction().getContext())));
119MI->addOperand(MachineOperand::CreateFPImm(Val));
120 }elseif (RegClass == &WebAssembly::V128RegClass) {
121MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
122MI->addOperand(MachineOperand::CreateImm(0));
123MI->addOperand(MachineOperand::CreateImm(0));
124 }else {
125llvm_unreachable("Unexpected reg class");
126 }
127}
128
129// Determine whether a call to the callee referenced by
130// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
131// effects.
132staticvoidqueryCallee(constMachineInstr &MI,bool &Read,bool &Write,
133bool &Effects,bool &StackPointer) {
134// All calls can use the stack pointer.
135 StackPointer =true;
136
137constMachineOperand &MO =WebAssembly::getCalleeOp(MI);
138if (MO.isGlobal()) {
139constConstant *GV = MO.getGlobal();
140if (constauto *GA = dyn_cast<GlobalAlias>(GV))
141if (!GA->isInterposable())
142 GV = GA->getAliasee();
143
144if (constauto *F = dyn_cast<Function>(GV)) {
145if (!F->doesNotThrow())
146 Effects =true;
147if (F->doesNotAccessMemory())
148return;
149if (F->onlyReadsMemory()) {
150Read =true;
151return;
152 }
153 }
154 }
155
156// Assume the worst.
157Write =true;
158Read =true;
159 Effects =true;
160}
161
162// Determine whether MI reads memory, writes memory, has side effects,
163// and/or uses the stack pointer value.
164staticvoidquery(constMachineInstr &MI,bool &Read,bool &Write,
165bool &Effects,bool &StackPointer) {
166assert(!MI.isTerminator());
167
168if (MI.isDebugInstr() ||MI.isPosition())
169return;
170
171// Check for loads.
172if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
173Read =true;
174
175// Check for stores.
176if (MI.mayStore()) {
177Write =true;
178 }elseif (MI.hasOrderedMemoryRef()) {
179switch (MI.getOpcode()) {
180case WebAssembly::DIV_S_I32:
181case WebAssembly::DIV_S_I64:
182case WebAssembly::REM_S_I32:
183case WebAssembly::REM_S_I64:
184case WebAssembly::DIV_U_I32:
185case WebAssembly::DIV_U_I64:
186case WebAssembly::REM_U_I32:
187case WebAssembly::REM_U_I64:
188case WebAssembly::I32_TRUNC_S_F32:
189case WebAssembly::I64_TRUNC_S_F32:
190case WebAssembly::I32_TRUNC_S_F64:
191case WebAssembly::I64_TRUNC_S_F64:
192case WebAssembly::I32_TRUNC_U_F32:
193case WebAssembly::I64_TRUNC_U_F32:
194case WebAssembly::I32_TRUNC_U_F64:
195case WebAssembly::I64_TRUNC_U_F64:
196// These instruction have hasUnmodeledSideEffects() returning true
197// because they trap on overflow and invalid so they can't be arbitrarily
198// moved, however hasOrderedMemoryRef() interprets this plus their lack
199// of memoperands as having a potential unknown memory reference.
200break;
201default:
202// Record volatile accesses, unless it's a call, as calls are handled
203// specially below.
204if (!MI.isCall()) {
205Write =true;
206 Effects =true;
207 }
208break;
209 }
210 }
211
212// Check for side effects.
213if (MI.hasUnmodeledSideEffects()) {
214switch (MI.getOpcode()) {
215case WebAssembly::DIV_S_I32:
216case WebAssembly::DIV_S_I64:
217case WebAssembly::REM_S_I32:
218case WebAssembly::REM_S_I64:
219case WebAssembly::DIV_U_I32:
220case WebAssembly::DIV_U_I64:
221case WebAssembly::REM_U_I32:
222case WebAssembly::REM_U_I64:
223case WebAssembly::I32_TRUNC_S_F32:
224case WebAssembly::I64_TRUNC_S_F32:
225case WebAssembly::I32_TRUNC_S_F64:
226case WebAssembly::I64_TRUNC_S_F64:
227case WebAssembly::I32_TRUNC_U_F32:
228case WebAssembly::I64_TRUNC_U_F32:
229case WebAssembly::I32_TRUNC_U_F64:
230case WebAssembly::I64_TRUNC_U_F64:
231// These instructions have hasUnmodeledSideEffects() returning true
232// because they trap on overflow and invalid so they can't be arbitrarily
233// moved, however in the specific case of register stackifying, it is safe
234// to move them because overflow and invalid are Undefined Behavior.
235break;
236default:
237 Effects =true;
238break;
239 }
240 }
241
242// Check for writes to __stack_pointer global.
243if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
244MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
245 strcmp(MI.getOperand(0).getSymbolName(),"__stack_pointer") == 0)
246 StackPointer =true;
247
248// Analyze calls.
249if (MI.isCall()) {
250queryCallee(MI,Read,Write, Effects, StackPointer);
251 }
252}
253
254// Test whether Def is safe and profitable to rematerialize.
255staticboolshouldRematerialize(constMachineInstr &Def,
256constWebAssemblyInstrInfo *TII) {
257return Def.isAsCheapAsAMove() &&TII->isTriviallyReMaterializable(Def);
258}
259
260// Identify the definition for this register at this point. This is a
261// generalization of MachineRegisterInfo::getUniqueVRegDef that uses
262// LiveIntervals to handle complex cases.
263staticMachineInstr *getVRegDef(unsigned Reg,constMachineInstr *Insert,
264constMachineRegisterInfo &MRI,
265constLiveIntervals &LIS) {
266// Most registers are in SSA form here so we try a quick MRI query first.
267if (MachineInstr *Def =MRI.getUniqueVRegDef(Reg))
268return Def;
269
270// MRI doesn't know what the Def is. Try asking LIS.
271if (constVNInfo *ValNo = LIS.getInterval(Reg).getVNInfoBefore(
272 LIS.getInstructionIndex(*Insert)))
273return LIS.getInstructionFromIndex(ValNo->def);
274
275returnnullptr;
276}
277
278// Test whether Reg, as defined at Def, has exactly one use. This is a
279// generalization of MachineRegisterInfo::hasOneNonDBGUse that uses
280// LiveIntervals to handle complex cases.
281staticboolhasOneNonDBGUse(unsigned Reg,MachineInstr *Def,
282MachineRegisterInfo &MRI,MachineDominatorTree &MDT,
283LiveIntervals &LIS) {
284// Most registers are in SSA form here so we try a quick MRI query first.
285if (MRI.hasOneNonDBGUse(Reg))
286returntrue;
287
288bool HasOne =false;
289constLiveInterval &LI = LIS.getInterval(Reg);
290constVNInfo *DefVNI =
291 LI.getVNInfoAt(LIS.getInstructionIndex(*Def).getRegSlot());
292assert(DefVNI);
293for (auto &I :MRI.use_nodbg_operands(Reg)) {
294constauto &Result = LI.Query(LIS.getInstructionIndex(*I.getParent()));
295if (Result.valueIn() == DefVNI) {
296if (!Result.isKill())
297returnfalse;
298if (HasOne)
299returnfalse;
300 HasOne =true;
301 }
302 }
303return HasOne;
304}
305
306// Test whether it's safe to move Def to just before Insert.
307// TODO: Compute memory dependencies in a way that doesn't require always
308// walking the block.
309// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
310// more precise.
311staticboolisSafeToMove(constMachineOperand *Def,constMachineOperand *Use,
312constMachineInstr *Insert,
313constWebAssemblyFunctionInfo &MFI,
314constMachineRegisterInfo &MRI) {
315constMachineInstr *DefI = Def->getParent();
316constMachineInstr *UseI =Use->getParent();
317assert(DefI->getParent() == Insert->getParent());
318assert(UseI->getParent() == Insert->getParent());
319
320// The first def of a multivalue instruction can be stackified by moving,
321// since the later defs can always be placed into locals if necessary. Later
322// defs can only be stackified if all previous defs are already stackified
323// since ExplicitLocals will not know how to place a def in a local if a
324// subsequent def is stackified. But only one def can be stackified by moving
325// the instruction, so it must be the first one.
326//
327// TODO: This could be loosened to be the first *live* def, but care would
328// have to be taken to ensure the drops of the initial dead defs can be
329// placed. This would require checking that no previous defs are used in the
330// same instruction as subsequent defs.
331if (Def != DefI->defs().begin())
332returnfalse;
333
334// If any subsequent def is used prior to the current value by the same
335// instruction in which the current value is used, we cannot
336// stackify. Stackifying in this case would require that def moving below the
337// current def in the stack, which cannot be achieved, even with locals.
338// Also ensure we don't sink the def past any other prior uses.
339for (constauto &SubsequentDef :drop_begin(DefI->defs())) {
340autoI = std::next(MachineBasicBlock::const_iterator(DefI));
341auto E = std::next(MachineBasicBlock::const_iterator(UseI));
342for (;I != E; ++I) {
343for (constauto &PriorUse :I->uses()) {
344if (&PriorUse ==Use)
345break;
346if (PriorUse.isReg() && SubsequentDef.getReg() == PriorUse.getReg())
347returnfalse;
348 }
349 }
350 }
351
352// If moving is a semantic nop, it is always allowed
353constMachineBasicBlock *MBB = DefI->getParent();
354auto NextI = std::next(MachineBasicBlock::const_iterator(DefI));
355for (auto E =MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
356 ;
357if (NextI == Insert)
358returntrue;
359
360// 'catch' and 'catch_all' should be the first instruction of a BB and cannot
361// move.
362if (WebAssembly::isCatch(DefI->getOpcode()))
363returnfalse;
364
365// Check for register dependencies.
366SmallVector<unsigned, 4> MutableRegisters;
367for (constMachineOperand &MO : DefI->operands()) {
368if (!MO.isReg() || MO.isUndef())
369continue;
370Register Reg = MO.getReg();
371
372// If the register is dead here and at Insert, ignore it.
373if (MO.isDead() && Insert->definesRegister(Reg,/*TRI=*/nullptr) &&
374 !Insert->readsRegister(Reg,/*TRI=*/nullptr))
375continue;
376
377if (Reg.isPhysical()) {
378// Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
379// from moving down, and we've already checked for that.
380if (Reg == WebAssembly::ARGUMENTS)
381continue;
382// If the physical register is never modified, ignore it.
383if (!MRI.isPhysRegModified(Reg))
384continue;
385// Otherwise, it's a physical register with unknown liveness.
386returnfalse;
387 }
388
389// If one of the operands isn't in SSA form, it has different values at
390// different times, and we need to make sure we don't move our use across
391// a different def.
392if (!MO.isDef() && !MRI.hasOneDef(Reg))
393 MutableRegisters.push_back(Reg);
394 }
395
396boolRead =false,Write =false, Effects =false, StackPointer =false;
397query(*DefI,Read,Write, Effects, StackPointer);
398
399// If the instruction does not access memory and has no side effects, it has
400// no additional dependencies.
401bool HasMutableRegisters = !MutableRegisters.empty();
402if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
403returntrue;
404
405// Scan through the intervening instructions between DefI and Insert.
406MachineBasicBlock::const_iteratorD(DefI),I(Insert);
407for (--I;I !=D; --I) {
408bool InterveningRead =false;
409bool InterveningWrite =false;
410bool InterveningEffects =false;
411bool InterveningStackPointer =false;
412query(*I, InterveningRead, InterveningWrite, InterveningEffects,
413 InterveningStackPointer);
414if (Effects && InterveningEffects)
415returnfalse;
416if (Read && InterveningWrite)
417returnfalse;
418if (Write && (InterveningRead || InterveningWrite))
419returnfalse;
420if (StackPointer && InterveningStackPointer)
421returnfalse;
422
423for (unsigned Reg : MutableRegisters)
424for (constMachineOperand &MO :I->operands())
425if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
426returnfalse;
427 }
428
429returntrue;
430}
431
432/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
433staticbooloneUseDominatesOtherUses(unsigned Reg,constMachineOperand &OneUse,
434constMachineBasicBlock &MBB,
435constMachineRegisterInfo &MRI,
436constMachineDominatorTree &MDT,
437LiveIntervals &LIS,
438WebAssemblyFunctionInfo &MFI) {
439constLiveInterval &LI = LIS.getInterval(Reg);
440
441constMachineInstr *OneUseInst = OneUse.getParent();
442VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
443
444for (constMachineOperand &Use :MRI.use_nodbg_operands(Reg)) {
445if (&Use == &OneUse)
446continue;
447
448constMachineInstr *UseInst =Use.getParent();
449VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
450
451if (UseVNI != OneUseVNI)
452continue;
453
454if (UseInst == OneUseInst) {
455// Another use in the same instruction. We need to ensure that the one
456// selected use happens "before" it.
457if (&OneUse > &Use)
458returnfalse;
459 }else {
460// Test that the use is dominated by the one selected use.
461while (!MDT.dominates(OneUseInst, UseInst)) {
462// Actually, dominating is over-conservative. Test that the use would
463// happen after the one selected use in the stack evaluation order.
464//
465// This is needed as a consequence of using implicit local.gets for
466// uses and implicit local.sets for defs.
467if (UseInst->getDesc().getNumDefs() == 0)
468returnfalse;
469constMachineOperand &MO = UseInst->getOperand(0);
470if (!MO.isReg())
471returnfalse;
472Register DefReg = MO.getReg();
473if (!DefReg.isVirtual() || !MFI.isVRegStackified(DefReg))
474returnfalse;
475assert(MRI.hasOneNonDBGUse(DefReg));
476constMachineOperand &NewUse = *MRI.use_nodbg_begin(DefReg);
477constMachineInstr *NewUseInst = NewUse.getParent();
478if (NewUseInst == OneUseInst) {
479if (&OneUse > &NewUse)
480returnfalse;
481break;
482 }
483 UseInst = NewUseInst;
484 }
485 }
486 }
487returntrue;
488}
489
490/// Get the appropriate tee opcode for the given register class.
491staticunsignedgetTeeOpcode(constTargetRegisterClass *RC) {
492if (RC == &WebAssembly::I32RegClass)
493return WebAssembly::TEE_I32;
494if (RC == &WebAssembly::I64RegClass)
495return WebAssembly::TEE_I64;
496if (RC == &WebAssembly::F32RegClass)
497return WebAssembly::TEE_F32;
498if (RC == &WebAssembly::F64RegClass)
499return WebAssembly::TEE_F64;
500if (RC == &WebAssembly::V128RegClass)
501return WebAssembly::TEE_V128;
502if (RC == &WebAssembly::EXTERNREFRegClass)
503return WebAssembly::TEE_EXTERNREF;
504if (RC == &WebAssembly::FUNCREFRegClass)
505return WebAssembly::TEE_FUNCREF;
506if (RC == &WebAssembly::EXNREFRegClass)
507return WebAssembly::TEE_EXNREF;
508llvm_unreachable("Unexpected register class");
509}
510
511// Shrink LI to its uses, cleaning up LI.
512staticvoidshrinkToUses(LiveInterval &LI,LiveIntervals &LIS) {
513if (LIS.shrinkToUses(&LI)) {
514SmallVector<LiveInterval *, 4> SplitLIs;
515 LIS.splitSeparateComponents(LI, SplitLIs);
516 }
517}
518
519/// A single-use def in the same block with no intervening memory or register
520/// dependencies; move the def down and nest it with the current instruction.
521staticMachineInstr *moveForSingleUse(unsigned Reg,MachineOperand &Op,
522MachineInstr *Def,MachineBasicBlock &MBB,
523MachineInstr *Insert,LiveIntervals &LIS,
524WebAssemblyFunctionInfo &MFI,
525MachineRegisterInfo &MRI) {
526LLVM_DEBUG(dbgs() <<"Move for single use: "; Def->dump());
527
528WebAssemblyDebugValueManager DefDIs(Def);
529 DefDIs.sink(Insert);
530 LIS.handleMove(*Def);
531
532if (MRI.hasOneDef(Reg) &&MRI.hasOneNonDBGUse(Reg)) {
533// No one else is using this register for anything so we can just stackify
534// it in place.
535 MFI.stackifyVReg(MRI, Reg);
536 }else {
537// The register may have unrelated uses or defs; create a new register for
538// just our one def and use so that we can stackify it.
539Register NewReg =MRI.createVirtualRegister(MRI.getRegClass(Reg));
540Op.setReg(NewReg);
541 DefDIs.updateReg(NewReg);
542
543// Tell LiveIntervals about the new register.
544 LIS.createAndComputeVirtRegInterval(NewReg);
545
546// Tell LiveIntervals about the changes to the old register.
547LiveInterval &LI = LIS.getInterval(Reg);
548 LI.removeSegment(LIS.getInstructionIndex(*Def).getRegSlot(),
549 LIS.getInstructionIndex(*Op.getParent()).getRegSlot(),
550/*RemoveDeadValNo=*/true);
551
552 MFI.stackifyVReg(MRI, NewReg);
553
554LLVM_DEBUG(dbgs() <<" - Replaced register: "; Def->dump());
555 }
556
557imposeStackOrdering(Def);
558return Def;
559}
560
561staticMachineInstr *getPrevNonDebugInst(MachineInstr *MI) {
562for (auto *I =MI->getPrevNode();I;I =I->getPrevNode())
563if (!I->isDebugInstr())
564returnI;
565returnnullptr;
566}
567
568/// A trivially cloneable instruction; clone it and nest the new copy with the
569/// current instruction.
570staticMachineInstr *rematerializeCheapDef(
571unsigned Reg,MachineOperand &Op,MachineInstr &Def,MachineBasicBlock &MBB,
572MachineBasicBlock::instr_iterator Insert,LiveIntervals &LIS,
573WebAssemblyFunctionInfo &MFI,MachineRegisterInfo &MRI,
574constWebAssemblyInstrInfo *TII,constWebAssemblyRegisterInfo *TRI) {
575LLVM_DEBUG(dbgs() <<"Rematerializing cheap def: "; Def.dump());
576LLVM_DEBUG(dbgs() <<" - for use in ";Op.getParent()->dump());
577
578WebAssemblyDebugValueManager DefDIs(&Def);
579
580Register NewReg =MRI.createVirtualRegister(MRI.getRegClass(Reg));
581 DefDIs.cloneSink(&*Insert, NewReg);
582Op.setReg(NewReg);
583MachineInstr *Clone =getPrevNonDebugInst(&*Insert);
584assert(Clone);
585 LIS.InsertMachineInstrInMaps(*Clone);
586 LIS.createAndComputeVirtRegInterval(NewReg);
587 MFI.stackifyVReg(MRI, NewReg);
588imposeStackOrdering(Clone);
589
590LLVM_DEBUG(dbgs() <<" - Cloned to "; Clone->dump());
591
592// Shrink the interval.
593boolIsDead =MRI.use_empty(Reg);
594if (!IsDead) {
595LiveInterval &LI = LIS.getInterval(Reg);
596shrinkToUses(LI, LIS);
597IsDead = !LI.liveAt(LIS.getInstructionIndex(Def).getDeadSlot());
598 }
599
600// If that was the last use of the original, delete the original.
601if (IsDead) {
602LLVM_DEBUG(dbgs() <<" - Deleting original\n");
603SlotIndexIdx = LIS.getInstructionIndex(Def).getRegSlot();
604 LIS.removePhysRegDefAt(MCRegister::from(WebAssembly::ARGUMENTS),Idx);
605 LIS.removeInterval(Reg);
606 LIS.RemoveMachineInstrFromMaps(Def);
607 DefDIs.removeDef();
608 }
609
610return Clone;
611}
612
613/// A multiple-use def in the same block with no intervening memory or register
614/// dependencies; move the def down, nest it with the current instruction, and
615/// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
616/// this:
617///
618/// Reg = INST ... // Def
619/// INST ..., Reg, ... // Insert
620/// INST ..., Reg, ...
621/// INST ..., Reg, ...
622///
623/// to this:
624///
625/// DefReg = INST ... // Def (to become the new Insert)
626/// TeeReg, Reg = TEE_... DefReg
627/// INST ..., TeeReg, ... // Insert
628/// INST ..., Reg, ...
629/// INST ..., Reg, ...
630///
631/// with DefReg and TeeReg stackified. This eliminates a local.get from the
632/// resulting code.
633staticMachineInstr *moveAndTeeForMultiUse(
634unsigned Reg,MachineOperand &Op,MachineInstr *Def,MachineBasicBlock &MBB,
635MachineInstr *Insert,LiveIntervals &LIS,WebAssemblyFunctionInfo &MFI,
636MachineRegisterInfo &MRI,constWebAssemblyInstrInfo *TII) {
637LLVM_DEBUG(dbgs() <<"Move and tee for multi-use:"; Def->dump());
638
639constauto *RegClass =MRI.getRegClass(Reg);
640Register TeeReg =MRI.createVirtualRegister(RegClass);
641Register DefReg =MRI.createVirtualRegister(RegClass);
642
643// Move Def into place.
644WebAssemblyDebugValueManager DefDIs(Def);
645 DefDIs.sink(Insert);
646 LIS.handleMove(*Def);
647
648// Create the Tee and attach the registers.
649MachineOperand &DefMO = Def->getOperand(0);
650MachineInstr *Tee =BuildMI(MBB, Insert, Insert->getDebugLoc(),
651TII->get(getTeeOpcode(RegClass)), TeeReg)
652 .addReg(Reg,RegState::Define)
653 .addReg(DefReg,getUndefRegState(DefMO.isDead()));
654Op.setReg(TeeReg);
655 DefDIs.updateReg(DefReg);
656SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
657SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
658
659// Tell LiveIntervals we moved the original vreg def from Def to Tee.
660LiveInterval &LI = LIS.getInterval(Reg);
661LiveInterval::iteratorI = LI.FindSegmentContaining(DefIdx);
662VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
663I->start = TeeIdx;
664 ValNo->def = TeeIdx;
665shrinkToUses(LI, LIS);
666
667// Finish stackifying the new regs.
668 LIS.createAndComputeVirtRegInterval(TeeReg);
669 LIS.createAndComputeVirtRegInterval(DefReg);
670 MFI.stackifyVReg(MRI, DefReg);
671 MFI.stackifyVReg(MRI, TeeReg);
672imposeStackOrdering(Def);
673imposeStackOrdering(Tee);
674
675// Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone
676// DBG_VALUEs for both of them, given that the latter will cancel the former
677// anyway. Here we only clone DBG_VALUEs for TeeReg, which will be converted
678// to a local index in ExplicitLocals pass.
679 DefDIs.cloneSink(Insert, TeeReg,/* CloneDef */false);
680
681LLVM_DEBUG(dbgs() <<" - Replaced register: "; Def->dump());
682LLVM_DEBUG(dbgs() <<" - Tee instruction: "; Tee->dump());
683return Def;
684}
685
686namespace{
687/// A stack for walking the tree of instructions being built, visiting the
688/// MachineOperands in DFS order.
689classTreeWalkerState {
690usingmop_iterator =MachineInstr::mop_iterator;
691usingmop_reverse_iterator = std::reverse_iterator<mop_iterator>;
692usingRangeTy =iterator_range<mop_reverse_iterator>;
693SmallVector<RangeTy, 4> Worklist;
694
695public:
696explicit TreeWalkerState(MachineInstr *Insert) {
697constiterator_range<mop_iterator> &Range =Insert->explicit_uses();
698if (!Range.empty())
699 Worklist.push_back(reverse(Range));
700 }
701
702bool done() const{return Worklist.empty(); }
703
704MachineOperand &pop() {
705 RangeTy &Range = Worklist.back();
706MachineOperand &Op = *Range.begin();
707Range =drop_begin(Range);
708if (Range.empty())
709 Worklist.pop_back();
710assert((Worklist.empty() || !Worklist.back().empty()) &&
711"Empty ranges shouldn't remain in the worklist");
712returnOp;
713 }
714
715 /// Push Instr's operands onto the stack to be visited.
716void pushOperands(MachineInstr *Instr) {
717constiterator_range<mop_iterator> &Range(Instr->explicit_uses());
718if (!Range.empty())
719 Worklist.push_back(reverse(Range));
720 }
721
722 /// Some of Instr's operands are on the top of the stack; remove them and
723 /// re-insert them starting from the beginning (because we've commuted them).
724void resetTopOperands(MachineInstr *Instr) {
725assert(hasRemainingOperands(Instr) &&
726"Reseting operands should only be done when the instruction has "
727"an operand still on the stack");
728 Worklist.back() =reverse(Instr->explicit_uses());
729 }
730
731 /// Test whether Instr has operands remaining to be visited at the top of
732 /// the stack.
733bool hasRemainingOperands(constMachineInstr *Instr) const{
734if (Worklist.empty())
735returnfalse;
736const RangeTy &Range = Worklist.back();
737return !Range.empty() &&Range.begin()->getParent() ==Instr;
738 }
739
740 /// Test whether the given register is present on the stack, indicating an
741 /// operand in the tree that we haven't visited yet. Moving a definition of
742 /// Reg to a point in the tree after that would change its value.
743 ///
744 /// This is needed as a consequence of using implicit local.gets for
745 /// uses and implicit local.sets for defs.
746bool isOnStack(unsigned Reg) const{
747for (const RangeTy &Range : Worklist)
748for (constMachineOperand &MO :Range)
749if (MO.isReg() && MO.getReg() == Reg)
750returntrue;
751returnfalse;
752 }
753};
754
755/// State to keep track of whether commuting is in flight or whether it's been
756/// tried for the current instruction and didn't work.
757classCommutingState {
758 /// There are effectively three states: the initial state where we haven't
759 /// started commuting anything and we don't know anything yet, the tentative
760 /// state where we've commuted the operands of the current instruction and are
761 /// revisiting it, and the declined state where we've reverted the operands
762 /// back to their original order and will no longer commute it further.
763bool TentativelyCommuting =false;
764bool Declined =false;
765
766 /// During the tentative state, these hold the operand indices of the commuted
767 /// operands.
768unsigned Operand0, Operand1;
769
770public:
771 /// Stackification for an operand was not successful due to ordering
772 /// constraints. If possible, and if we haven't already tried it and declined
773 /// it, commute Insert's operands and prepare to revisit it.
774void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
775constWebAssemblyInstrInfo *TII) {
776if (TentativelyCommuting) {
777assert(!Declined &&
778"Don't decline commuting until you've finished trying it");
779// Commuting didn't help. Revert it.
780TII->commuteInstruction(*Insert,/*NewMI=*/false, Operand0, Operand1);
781 TentativelyCommuting =false;
782 Declined =true;
783 }elseif (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
784 Operand0 =TargetInstrInfo::CommuteAnyOperandIndex;
785 Operand1 =TargetInstrInfo::CommuteAnyOperandIndex;
786if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
787// Tentatively commute the operands and try again.
788TII->commuteInstruction(*Insert,/*NewMI=*/false, Operand0, Operand1);
789 TreeWalker.resetTopOperands(Insert);
790 TentativelyCommuting =true;
791 Declined =false;
792 }
793 }
794 }
795
796 /// Stackification for some operand was successful. Reset to the default
797 /// state.
798void reset() {
799 TentativelyCommuting =false;
800 Declined =false;
801 }
802};
803}// end anonymous namespace
804
805bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
806LLVM_DEBUG(dbgs() <<"********** Register Stackifying **********\n"
807"********** Function: "
808 << MF.getName() <<'\n');
809
810bool Changed =false;
811MachineRegisterInfo &MRI = MF.getRegInfo();
812WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
813constauto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
814constauto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
815auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
816auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
817
818// Walk the instructions from the bottom up. Currently we don't look past
819// block boundaries, and the blocks aren't ordered so the block visitation
820// order isn't significant, but we may want to change this in the future.
821for (MachineBasicBlock &MBB : MF) {
822// Don't use a range-based for loop, because we modify the list as we're
823// iterating over it and the end iterator may change.
824for (auto MII =MBB.rbegin(); MII !=MBB.rend(); ++MII) {
825MachineInstr *Insert = &*MII;
826// Don't nest anything inside an inline asm, because we don't have
827// constraints for $push inputs.
828if (Insert->isInlineAsm())
829continue;
830
831// Ignore debugging intrinsics.
832if (Insert->isDebugValue())
833continue;
834
835// Iterate through the inputs in reverse order, since we'll be pulling
836// operands off the stack in LIFO order.
837 CommutingState Commuting;
838 TreeWalkerState TreeWalker(Insert);
839while (!TreeWalker.done()) {
840MachineOperand &Use = TreeWalker.pop();
841
842// We're only interested in explicit virtual register operands.
843if (!Use.isReg())
844continue;
845
846RegisterReg =Use.getReg();
847assert(Use.isUse() &&"explicit_uses() should only iterate over uses");
848assert(!Use.isImplicit() &&
849"explicit_uses() should only iterate over explicit operands");
850if (Reg.isPhysical())
851continue;
852
853// Identify the definition for this register at this point.
854MachineInstr *DefI =getVRegDef(Reg, Insert,MRI, LIS);
855if (!DefI)
856continue;
857
858// Don't nest an INLINE_ASM def into anything, because we don't have
859// constraints for $pop outputs.
860if (DefI->isInlineAsm())
861continue;
862
863// Argument instructions represent live-in registers and not real
864// instructions.
865if (WebAssembly::isArgument(DefI->getOpcode()))
866continue;
867
868MachineOperand *Def =
869 DefI->findRegisterDefOperand(Reg,/*TRI=*/nullptr);
870assert(Def !=nullptr);
871
872// Decide which strategy to take. Prefer to move a single-use value
873// over cloning it, and prefer cloning over introducing a tee.
874// For moving, we require the def to be in the same block as the use;
875// this makes things simpler (LiveIntervals' handleMove function only
876// supports intra-block moves) and it's MachineSink's job to catch all
877// the sinking opportunities anyway.
878bool SameBlock = DefI->getParent() == &MBB;
879bool CanMove = SameBlock &&isSafeToMove(Def, &Use, Insert, MFI,MRI) &&
880 !TreeWalker.isOnStack(Reg);
881if (CanMove &&hasOneNonDBGUse(Reg, DefI,MRI, MDT, LIS)) {
882Insert =moveForSingleUse(Reg,Use, DefI,MBB, Insert, LIS, MFI,MRI);
883
884// If we are removing the frame base reg completely, remove the debug
885// info as well.
886// TODO: Encode this properly as a stackified value.
887if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg)
888 MFI.clearFrameBaseVreg();
889 }elseif (shouldRematerialize(*DefI,TII)) {
890Insert =
891rematerializeCheapDef(Reg,Use, *DefI,MBB,Insert->getIterator(),
892 LIS, MFI,MRI,TII,TRI);
893 }elseif (CanMove &&oneUseDominatesOtherUses(Reg,Use,MBB,MRI, MDT,
894 LIS, MFI)) {
895Insert =moveAndTeeForMultiUse(Reg,Use, DefI,MBB, Insert, LIS, MFI,
896MRI,TII);
897 }else {
898// We failed to stackify the operand. If the problem was ordering
899// constraints, Commuting may be able to help.
900if (!CanMove && SameBlock)
901 Commuting.maybeCommute(Insert, TreeWalker,TII);
902// Proceed to the next operand.
903continue;
904 }
905
906// Stackifying a multivalue def may unlock in-place stackification of
907// subsequent defs. TODO: Handle the case where the consecutive uses are
908// not all in the same instruction.
909auto *SubsequentDef =Insert->defs().begin();
910auto *SubsequentUse = &Use;
911while (SubsequentDef !=Insert->defs().end() &&
912 SubsequentUse !=Use.getParent()->uses().end()) {
913if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
914break;
915Register DefReg = SubsequentDef->getReg();
916RegisterUseReg = SubsequentUse->getReg();
917// TODO: This single-use restriction could be relaxed by using tees
918if (DefReg !=UseReg || !MRI.hasOneNonDBGUse(DefReg))
919break;
920 MFI.stackifyVReg(MRI, DefReg);
921 ++SubsequentDef;
922 ++SubsequentUse;
923 }
924
925// If the instruction we just stackified is an IMPLICIT_DEF, convert it
926// to a constant 0 so that the def is explicit, and the push/pop
927// correspondence is maintained.
928if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
929convertImplicitDefToConstZero(Insert,MRI,TII, MF, LIS);
930
931// We stackified an operand. Add the defining instruction's operands to
932// the worklist stack now to continue to build an ever deeper tree.
933 Commuting.reset();
934 TreeWalker.pushOperands(Insert);
935 }
936
937// If we stackified any operands, skip over the tree to start looking for
938// the next instruction we can build a tree on.
939if (Insert != &*MII) {
940imposeStackOrdering(&*MII);
941 MII =MachineBasicBlock::iterator(Insert).getReverse();
942 Changed =true;
943 }
944 }
945 }
946
947// If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
948// that it never looks like a use-before-def.
949if (Changed) {
950 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
951for (MachineBasicBlock &MBB : MF)
952MBB.addLiveIn(WebAssembly::VALUE_STACK);
953 }
954
955#ifndef NDEBUG
956// Verify that pushes and pops are performed in LIFO order.
957SmallVector<unsigned, 0>Stack;
958for (MachineBasicBlock &MBB : MF) {
959for (MachineInstr &MI :MBB) {
960if (MI.isDebugInstr())
961continue;
962for (MachineOperand &MO :reverse(MI.explicit_uses())) {
963if (!MO.isReg())
964continue;
965RegisterReg = MO.getReg();
966if (MFI.isVRegStackified(Reg))
967assert(Stack.pop_back_val() == Reg &&
968"Register stack pop should be paired with a push");
969 }
970for (MachineOperand &MO :MI.defs()) {
971if (!MO.isReg())
972continue;
973RegisterReg = MO.getReg();
974if (MFI.isVRegStackified(Reg))
975Stack.push_back(MO.getReg());
976 }
977 }
978// TODO: Generalize this code to support keeping values on the stack across
979// basic block boundaries.
980assert(Stack.empty() &&
981"Register stack pushes and pops should be balanced");
982 }
983#endif
984
985return Changed;
986}
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Passes.h
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
Debug.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
GlobalAlias.h
UseReg
static Register UseReg(const MachineOperand &MO)
Definition:HexagonCopyToCombine.cpp:252
TII
const HexagonInstrInfo * TII
Definition:HexagonCopyToCombine.cpp:125
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
LiveIntervals.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachineBlockFrequencyInfo.h
MachineDominators.h
MachineInstrBuilder.h
MachineRegisterInfo.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition:MachineSink.cpp:2029
Range
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:38
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IsDead
bool IsDead
Definition:SILowerControlFlow.cpp:176
WebAssemblyDebugValueManager.h
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
WebAssemblyMCTargetDesc.h
This file provides WebAssembly-specific target descriptions.
WebAssemblyMachineFunctionInfo.h
This file declares WebAssembly-specific per-machine-function information.
rematerializeCheapDef
static MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI)
A trivially cloneable instruction; clone it and nest the new copy with the current instruction.
Definition:WebAssemblyRegStackify.cpp:570
getTeeOpcode
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
Definition:WebAssemblyRegStackify.cpp:491
getVRegDef
static MachineInstr * getVRegDef(unsigned Reg, const MachineInstr *Insert, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
Definition:WebAssemblyRegStackify.cpp:263
convertImplicitDefToConstZero
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF, LiveIntervals &LIS)
Definition:WebAssemblyRegStackify.cpp:96
hasOneNonDBGUse
static bool hasOneNonDBGUse(unsigned Reg, MachineInstr *Def, MachineRegisterInfo &MRI, MachineDominatorTree &MDT, LiveIntervals &LIS)
Definition:WebAssemblyRegStackify.cpp:281
isSafeToMove
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI)
Definition:WebAssemblyRegStackify.cpp:311
moveForSingleUse
static MachineInstr * moveForSingleUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI)
A single-use def in the same block with no intervening memory or register dependencies; move the def ...
Definition:WebAssemblyRegStackify.cpp:521
imposeStackOrdering
static void imposeStackOrdering(MachineInstr *MI)
Definition:WebAssemblyRegStackify.cpp:80
query
static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
Definition:WebAssemblyRegStackify.cpp:164
shrinkToUses
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
Definition:WebAssemblyRegStackify.cpp:512
getPrevNonDebugInst
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
Definition:WebAssemblyRegStackify.cpp:561
shouldRematerialize
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
Definition:WebAssemblyRegStackify.cpp:255
DEBUG_TYPE
#define DEBUG_TYPE
Definition:WebAssemblyRegStackify.cpp:40
moveAndTeeForMultiUse
static MachineInstr * moveAndTeeForMultiUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A multiple-use def in the same block with no intervening memory or register dependencies; move the de...
Definition:WebAssemblyRegStackify.cpp:633
oneUseDominatesOtherUses
static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, const MachineBasicBlock &MBB, const MachineRegisterInfo &MRI, const MachineDominatorTree &MDT, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI)
Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
Definition:WebAssemblyRegStackify.cpp:433
queryCallee
static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
Definition:WebAssemblyRegStackify.cpp:132
WebAssemblySubtarget.h
This file declares the WebAssembly-specific subclass of TargetSubtarget.
WebAssemblyUtilities.h
This file contains the declaration of the WebAssembly-specific utility functions.
WebAssembly.h
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
T
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition:PassAnalysisSupport.h:47
llvm::AnalysisUsage::addPreservedID
AnalysisUsage & addPreservedID(const void *ID)
Definition:PassAnalysisSupport.h:88
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition:PassAnalysisSupport.h:75
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition:PassAnalysisSupport.h:98
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition:Pass.cpp:256
llvm::Constant
This is an important base class in LLVM.
Definition:Constant.h:42
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition:Constants.cpp:373
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition:Pass.h:310
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition:Function.cpp:369
llvm::LiveInterval
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition:LiveInterval.h:687
llvm::LiveIntervalsWrapperPass
Definition:LiveIntervals.h:527
llvm::LiveIntervals
Definition:LiveIntervals.h:55
llvm::LiveIntervals::getInstructionFromIndex
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
Definition:LiveIntervals.h:250
llvm::LiveIntervals::InsertMachineInstrInMaps
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
Definition:LiveIntervals.h:283
llvm::LiveIntervals::handleMove
void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
Definition:LiveIntervals.cpp:1559
llvm::LiveIntervals::getInstructionIndex
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
Definition:LiveIntervals.h:245
llvm::LiveIntervals::RemoveMachineInstrFromMaps
void RemoveMachineInstrFromMaps(MachineInstr &MI)
Definition:LiveIntervals.h:293
llvm::LiveIntervals::getInterval
LiveInterval & getInterval(Register Reg)
Definition:LiveIntervals.h:133
llvm::LiveIntervals::removeInterval
void removeInterval(Register Reg)
Interval removal.
Definition:LiveIntervals.h:170
llvm::LiveIntervals::shrinkToUses
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
Definition:LiveIntervals.cpp:485
llvm::LiveIntervals::removePhysRegDefAt
void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
Definition:LiveIntervals.cpp:1776
llvm::LiveIntervals::splitSeparateComponents
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
Definition:LiveIntervals.cpp:1802
llvm::LiveIntervals::createAndComputeVirtRegInterval
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
Definition:LiveIntervals.h:156
llvm::LiveRange::liveAt
bool liveAt(SlotIndex index) const
Definition:LiveInterval.h:401
llvm::LiveRange::Query
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
Definition:LiveInterval.h:542
llvm::LiveRange::getVNInfoBefore
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
Definition:LiveInterval.h:429
llvm::LiveRange::FindSegmentContaining
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
Definition:LiveInterval.h:436
llvm::LiveRange::removeSegment
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
Definition:LiveInterval.cpp:566
llvm::LiveRange::getVNInfoAt
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Definition:LiveInterval.h:421
llvm::MCInstrDesc::getNumDefs
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition:MCInstrDesc.h:248
llvm::MCRegister::from
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition:MCRegister.h:78
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition:MachineBasicBlock.h:365
llvm::MachineBasicBlock::instr_iterator
Instructions::iterator instr_iterator
Definition:MachineBasicBlock.h:314
llvm::MachineBasicBlock::end
iterator end()
Definition:MachineBasicBlock.h:357
llvm::MachineBasicBlock::addLiveIn
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
Definition:MachineBasicBlock.h:456
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition:MachineBasicBlock.h:359
llvm::MachineBasicBlock::iterator
MachineInstrBundleIterator< MachineInstr > iterator
Definition:MachineBasicBlock.h:319
llvm::MachineBlockFrequencyInfoWrapperPass
Definition:MachineBlockFrequencyInfo.h:137
llvm::MachineDominatorTreeWrapperPass
Analysis pass which computes a MachineDominatorTree.
Definition:MachineDominators.h:131
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition:MachineDominators.h:75
llvm::MachineDominatorTree::dominates
bool dominates(const MachineInstr *A, const MachineInstr *B) const
Definition:MachineDominators.h:91
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition:MachineFunctionPass.h:30
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition:MachineFunctionPass.cpp:169
llvm::MachineFunctionPass::runOnMachineFunction
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition:MachineFunction.h:733
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition:MachineFunction.cpp:645
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition:MachineFunction.h:743
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition:MachineFunction.h:704
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition:MachineFunction.h:831
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition:MachineInstrBuilder.h:99
llvm::MachineInstrBundleIterator< const MachineInstr >
llvm::MachineInstrBundleIterator::getReverse
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Definition:MachineInstrBundleIterator.h:283
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition:MachineInstr.h:577
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition:MachineInstr.h:349
llvm::MachineInstr::isInlineAsm
bool isInlineAsm() const
Definition:MachineInstr.h:1412
llvm::MachineInstr::getDesc
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition:MachineInstr.h:574
llvm::MachineInstr::operands
iterator_range< mop_iterator > operands()
Definition:MachineInstr.h:693
llvm::MachineInstr::defs
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition:MachineInstr.h:730
llvm::MachineInstr::mop_iterator
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
Definition:MachineInstr.h:684
llvm::MachineInstr::dump
void dump() const
Definition:MachineInstr.cpp:1695
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition:MachineInstr.h:587
llvm::MachineInstr::findRegisterDefOperand
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
Definition:MachineInstr.h:1580
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition:MachineOperand.h:48
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition:MachineOperand.h:582
llvm::MachineOperand::CreateFPImm
static MachineOperand CreateFPImm(const ConstantFP *CFP)
Definition:MachineOperand.h:832
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition:MachineOperand.h:329
llvm::MachineOperand::getParent
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Definition:MachineOperand.h:243
llvm::MachineOperand::isDead
bool isDead() const
Definition:MachineOperand.h:394
llvm::MachineOperand::CreateImm
static MachineOperand CreateImm(int64_t Val)
Definition:MachineOperand.h:820
llvm::MachineOperand::isGlobal
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Definition:MachineOperand.h:347
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition:MachineOperand.h:369
llvm::MachineOperand::CreateReg
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)
Definition:MachineOperand.h:838
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition:MachineRegisterInfo.h:51
llvm::Pass::getPassName
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition:Pass.cpp:81
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::Register::isVirtual
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition:Register.h:91
llvm::SlotIndex
SlotIndex - An opaque wrapper around machine indexes.
Definition:SlotIndexes.h:65
llvm::SlotIndex::getDeadSlot
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition:SlotIndexes.h:242
llvm::SlotIndex::getRegSlot
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
Definition:SlotIndexes.h:237
llvm::SlotIndexesWrapperPass
Definition:SlotIndexes.h:663
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorTemplateBase::pop_back
void pop_back()
Definition:SmallVector.h:425
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition:TargetInstrInfo.h:112
llvm::TargetInstrInfo::CommuteAnyOperandIndex
static const unsigned CommuteAnyOperandIndex
Definition:TargetInstrInfo.h:461
llvm::TargetRegisterClass
Definition:TargetRegisterInfo.h:44
llvm::Type::getDoubleTy
static Type * getDoubleTy(LLVMContext &C)
llvm::Type::getFloatTy
static Type * getFloatTy(LLVMContext &C)
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition:Use.h:43
llvm::VNInfo
VNInfo - Value Number Information.
Definition:LiveInterval.h:53
llvm::VNInfo::def
SlotIndex def
The index of the defining instruction.
Definition:LiveInterval.h:61
llvm::Value::uses
iterator_range< use_iterator > uses()
Definition:Value.h:376
llvm::WebAssemblyDebugValueManager
Definition:WebAssemblyDebugValueManager.h:28
llvm::WebAssemblyDebugValueManager::updateReg
void updateReg(Register Reg)
Definition:WebAssemblyDebugValueManager.cpp:394
llvm::WebAssemblyDebugValueManager::removeDef
void removeDef()
Definition:WebAssemblyDebugValueManager.cpp:415
llvm::WebAssemblyDebugValueManager::cloneSink
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
Definition:WebAssemblyDebugValueManager.cpp:354
llvm::WebAssemblyDebugValueManager::sink
void sink(MachineInstr *Insert)
Definition:WebAssemblyDebugValueManager.cpp:253
llvm::WebAssemblyFunctionInfo
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
Definition:WebAssemblyMachineFunctionInfo.h:34
llvm::WebAssemblyFunctionInfo::isVRegStackified
bool isVRegStackified(unsigned VReg) const
Definition:WebAssemblyMachineFunctionInfo.h:134
llvm::WebAssemblyFunctionInfo::getFrameBaseVreg
unsigned getFrameBaseVreg() const
Definition:WebAssemblyMachineFunctionInfo.h:108
llvm::WebAssemblyFunctionInfo::stackifyVReg
void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg)
Definition:WebAssemblyMachineFunctionInfo.h:122
llvm::WebAssemblyFunctionInfo::clearFrameBaseVreg
void clearFrameBaseVreg()
Definition:WebAssemblyMachineFunctionInfo.h:112
llvm::WebAssemblyFunctionInfo::isFrameBaseVirtual
bool isFrameBaseVirtual() const
Definition:WebAssemblyMachineFunctionInfo.h:114
llvm::WebAssemblyInstrInfo
Definition:WebAssemblyInstrInfo.h:38
llvm::WebAssemblyRegisterInfo
Definition:WebAssemblyRegisterInfo.h:28
llvm::WebAssemblySubtarget
Definition:WebAssemblySubtarget.h:35
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition:iterator_range.h:42
unsigned
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::RegState::Define
@ Define
Register definition.
Definition:MachineInstrBuilder.h:46
llvm::WebAssembly::isArgument
bool isArgument(unsigned Opc)
Definition:WebAssemblyMCTargetDesc.h:337
llvm::WebAssembly::getCalleeOp
const MachineOperand & getCalleeOp(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
Definition:WebAssemblyUtilities.cpp:87
llvm::WebAssembly::isCatch
bool isCatch(unsigned Opc)
Definition:WebAssemblyMCTargetDesc.h:509
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition:X86DisassemblerDecoder.h:621
llvm::cfg::UpdateKind::Insert
@ Insert
llvm::pdb::PDB_MemoryType::Stack
@ Stack
llvm::rdf::Instr
NodeAddr< InstrNode * > Instr
Definition:RDFGraph.h:389
llvm::rdf::Def
NodeAddr< DefNode * > Def
Definition:RDFGraph.h:384
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition:STLExtras.h:329
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition:SparseBitVector.h:877
llvm::Read
@ Read
Definition:CodeGenData.h:107
llvm::Write
@ Write
Definition:CodeGenData.h:108
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition:MachineInstrBuilder.h:373
llvm::reverse
auto reverse(ContainerTy &&C)
Definition:STLExtras.h:420
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::getUndefRegState
unsigned getUndefRegState(bool B)
Definition:MachineInstrBuilder.h:561
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::LiveVariablesID
char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
Definition:LiveVariables.cpp:61
llvm::createWebAssemblyRegStackify
FunctionPass * createWebAssemblyRegStackify()
raw_ostream.h

Generated on Fri Jul 18 2025 14:46:15 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp