28 auto Key = std::make_pair(
MBB, Val);
29 auto It = VRegDefMap.find(
Key);
34 if (It == VRegDefMap.end()) {
38 VRegDefMap[
Key] = VReg;
39 VRegUpwardsUse[
Key] = VReg;
47 VRegDefMap[std::make_pair(
MBB, Val)] = VReg;
53 auto It = VRegDefUses.find(
Key);
54 if (It != VRegDefUses.end())
60 VRegDefUses[
Key] = VReg;
68 auto It = VRegDefUses.find(
Key);
69 if (It != VRegDefUses.end())
73 VRegDefUses[
Key] = VReg;
88 SwiftErrorVals.
clear();
90 VRegUpwardsUse.clear();
92 SwiftErrorArg =
nullptr;
95 bool HaveSeenSwiftErrorArg =
false;
98 if (AI->hasSwiftErrorAttr()) {
99 assert(!HaveSeenSwiftErrorArg &&
100 "Must have only one swifterror parameter");
101 (void)HaveSeenSwiftErrorArg;
102 HaveSeenSwiftErrorArg =
true;
103 SwiftErrorArg = &*AI;
107 for (
const auto &LLVMBB : *Fn)
108 for (
const auto &Inst : LLVMBB) {
109 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(&Inst))
110 if (Alloca->isSwiftError())
121 if (SwiftErrorVals.
empty())
127 bool Inserted =
false;
128 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
131 if (SwiftErrorArg && SwiftErrorArg == SwiftErrorVal)
137 TII->
get(TargetOpcode::IMPLICIT_DEF), VReg);
153 if (SwiftErrorVals.
empty())
160 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
161 auto Key = std::make_pair(
MBB, SwiftErrorVal);
162 auto UUseIt = VRegUpwardsUse.find(
Key);
163 auto VRegDefIt = VRegDefMap.find(
Key);
164 bool UpwardsUse = UUseIt != VRegUpwardsUse.end();
166 bool DownwardDef = VRegDefIt != VRegDefMap.end();
167 assert(!(UpwardsUse && !DownwardDef) &&
168 "We can't have an upwards use but no downwards def");
173 if (!UpwardsUse && DownwardDef)
184 if (!Visited.
insert(Pred).second)
195 UUseIt = VRegUpwardsUse.find(
Key);
196 assert(UUseIt != VRegUpwardsUse.end());
197 UUseVReg = UUseIt->second;
207 [&](
const std::pair<const MachineBasicBlock *, Register> &V)
208 ->
bool {
return V.second != VRegs[0].second; }) !=
213 if (!UpwardsUse && !needPHI) {
215 "No predecessors? The entry block should bail out earlier");
221 auto DLoc = isa<Instruction>(SwiftErrorVal)
222 ? cast<Instruction>(SwiftErrorVal)->getDebugLoc()
230 "No predecessors? Is the Calling Convention correct?");
234 .addReg(VRegs[0].second);
246 TII->
get(TargetOpcode::PHI), PHIVReg);
247 for (
auto BBRegPair : VRegs) {
266 for (
auto It = Begin; It != End; ++It) {
267 if (
auto *CB = dyn_cast<CallBase>(&*It)) {
269 const Value *SwiftErrorAddr =
nullptr;
270 for (
auto &
Arg : CB->args()) {
271 if (!
Arg->isSwiftError())
274 assert(!SwiftErrorAddr &&
"Cannot have multiple swifterror arguments");
275 SwiftErrorAddr = &*
Arg;
277 "Must have a swifterror value argument");
287 }
else if (
const LoadInst *LI = dyn_cast<const LoadInst>(&*It)) {
288 const Value *V = LI->getOperand(0);
295 }
else if (
const StoreInst *
SI = dyn_cast<const StoreInst>(&*It)) {
296 const Value *SwiftErrorAddr =
SI->getOperand(1);
304 }
else if (
const ReturnInst *R = dyn_cast<const ReturnInst>(&*It)) {
305 const Function *
F = R->getParent()->getParent();
306 if (!
F->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
Return a value (possibly void), from a function.
void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register)
Set the swifterror virtual register in the VRegDefMap for this basic block.
This class represents an incoming formal argument to a Function.
This class represents lattice values for constants.
LLVM_NODISCARD bool empty() const
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void push_back(const T &Elt)
virtual const TargetLowering * getTargetLowering() const
void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin, BasicBlock::const_iterator End)
An instruction for reading from memory.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Function & getFunction()
Return the LLVM function that this machine code represents.
InstListType::const_iterator const_iterator
void setFunction(MachineFunction &MF)
Initialize data structures for specified new function.
Register getOrCreateVRegUseAt(const Instruction *, const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register for a use of a swifterror by an instruction.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual bool supportSwiftError() const
Return true if the target supports swifterror attribute.
bool isSwiftError() const
Return true if this value is a swifterror value.
An instruction for storing to memory.
bool createEntriesInEntryBlock(DebugLoc DbgLoc)
Create initial definitions of swifterror values in the entry block of the current function.
virtual const TargetInstrInfo * getInstrInfo() const
Register getOrCreateVRegDefAt(const Instruction *, const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register for a def of a swifterror by an instruction.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
PointerIntPair - This class implements a pair of a pointer and small integer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
iterator_range< pred_iterator > predecessors()
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Register getOrCreateVReg(const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register in VRegDefMap for this basic block.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Promote Memory to Register
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
void propagateVRegs()
Propagate assigned swifterror vregs through a function, synthesizing PHI nodes when needed to maintai...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Wrapper class representing virtual and physical registers.
This file describes how to lower LLVM code to machine code.
an instruction to allocate memory on the stack
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL