27 auto Key = std::make_pair(
MBB, Val);
28 auto It = VRegDefMap.find(Key);
33 if (It == VRegDefMap.end()) {
37 VRegDefMap[Key] = VReg;
38 VRegUpwardsUse[Key] = VReg;
46 VRegDefMap[std::make_pair(
MBB, Val)] = VReg;
52 auto It = VRegDefUses.find(Key);
53 if (It != VRegDefUses.end())
59 VRegDefUses[Key] = VReg;
67 auto It = VRegDefUses.find(Key);
68 if (It != VRegDefUses.end())
72 VRegDefUses[Key] = VReg;
87 SwiftErrorVals.
clear();
89 VRegUpwardsUse.clear();
91 SwiftErrorArg =
nullptr;
94 bool HaveSeenSwiftErrorArg =
false;
97 if (AI->hasSwiftErrorAttr()) {
98 assert(!HaveSeenSwiftErrorArg &&
99 "Must have only one swifterror parameter");
100 (void)HaveSeenSwiftErrorArg;
101 HaveSeenSwiftErrorArg =
true;
102 SwiftErrorArg = &*AI;
106 for (
const auto &LLVMBB : *Fn)
107 for (
const auto &Inst : LLVMBB) {
108 if (
const AllocaInst *Alloca = dyn_cast<AllocaInst>(&Inst))
109 if (Alloca->isSwiftError())
120 if (SwiftErrorVals.
empty())
126 bool Inserted =
false;
127 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
130 if (SwiftErrorArg && SwiftErrorArg == SwiftErrorVal)
136 TII->
get(TargetOpcode::IMPLICIT_DEF), VReg);
152 if (SwiftErrorVals.
empty())
159 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
160 auto Key = std::make_pair(
MBB, SwiftErrorVal);
161 auto UUseIt = VRegUpwardsUse.find(Key);
162 auto VRegDefIt = VRegDefMap.find(Key);
163 bool UpwardsUse = UUseIt != VRegUpwardsUse.end();
165 bool DownwardDef = VRegDefIt != VRegDefMap.end();
166 assert(!(UpwardsUse && !DownwardDef) &&
167 "We can't have an upwards use but no downwards def");
172 if (!UpwardsUse && DownwardDef)
183 if (!Visited.
insert(Pred).second)
194 UUseIt = VRegUpwardsUse.find(Key);
195 assert(UUseIt != VRegUpwardsUse.end());
196 UUseVReg = UUseIt->second;
206 [&](
const std::pair<const MachineBasicBlock *, Register> &V)
207 ->
bool {
return V.second != VRegs[0].second; });
211 if (!UpwardsUse && !needPHI) {
213 "No predecessors? The entry block should bail out earlier");
219 auto DLoc = isa<Instruction>(SwiftErrorVal)
220 ? cast<Instruction>(SwiftErrorVal)->getDebugLoc()
228 "No predecessors? Is the Calling Convention correct?");
244 TII->
get(TargetOpcode::PHI), PHIVReg);
245 for (
auto BBRegPair : VRegs) {
246 PHI.addReg(BBRegPair.second).addMBB(BBRegPair.first);
258 for (
const auto &
Use : VRegUpwardsUse) {
261 if (!
MRI.def_empty(VReg))
264#ifdef EXPENSIVE_CHECKS
266 "Reachable block has VReg upward use without definition.");
272 TII->
get(TargetOpcode::IMPLICIT_DEF), VReg);
283 for (
auto It = Begin; It !=
End; ++It) {
284 if (
auto *CB = dyn_cast<CallBase>(&*It)) {
286 const Value *SwiftErrorAddr =
nullptr;
287 for (
const auto &Arg : CB->args()) {
288 if (!Arg->isSwiftError())
291 assert(!SwiftErrorAddr &&
"Cannot have multiple swifterror arguments");
292 SwiftErrorAddr = &*Arg;
294 "Must have a swifterror value argument");
304 }
else if (
const LoadInst *LI = dyn_cast<const LoadInst>(&*It)) {
305 const Value *V = LI->getOperand(0);
306 if (!V->isSwiftError())
312 }
else if (
const StoreInst *SI = dyn_cast<const StoreInst>(&*It)) {
313 const Value *SwiftErrorAddr = SI->getOperand(1);
321 }
else if (
const ReturnInst *R = dyn_cast<const ReturnInst>(&*It)) {
322 const Function *
F = R->getParent()->getParent();
323 if (!
F->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file describes how to lower LLVM code to machine code.
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
InstListType::const_iterator const_iterator
An instruction for reading from memory.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
iterator_range< pred_iterator > predecessors()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
PointerIntPair - This class implements a pair of a pointer and small integer.
Wrapper class representing virtual and physical registers.
Return a value (possibly void), from a function.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
bool createEntriesInEntryBlock(DebugLoc DbgLoc)
Create initial definitions of swifterror values in the entry block of the current function.
void setFunction(MachineFunction &MF)
Initialize data structures for specified new function.
Register getOrCreateVReg(const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register in VRegDefMap for this basic block.
void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register)
Set the swifterror virtual register in the VRegDefMap for this basic block.
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.
void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin, BasicBlock::const_iterator End)
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.
void propagateVRegs()
Propagate assigned swifterror vregs through a function, synthesizing PHI nodes when needed to maintai...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
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...
virtual bool supportSwiftError() const
Return true if the target supports swifterror attribute.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.