1 //===- SwiftErrorValueTracking.h - Track swifterror VReg vals --*- C++ -*--===//
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 // This implements a limited mem2reg-like analysis to promote uses of function
10 // arguments and allocas marked with swiftalloc from memory into virtual
11 // registers tracked by this class.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_SWIFTERRORVALUETRACKING_H
16 #define LLVM_CODEGEN_SWIFTERRORVALUETRACKING_H
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/CodeGen/Register.h"
21 #include "llvm/IR/BasicBlock.h"
22 #include "llvm/IR/DebugLoc.h"
23 #include <utility>
24 
25 
26 namespace llvm {
27   class Function;
28   class MachineBasicBlock;
29   class MachineFunction;
30   class MachineInstr;
31   class TargetInstrInfo;
32   class TargetLowering;
33 
34 class SwiftErrorValueTracking {
35   // Some useful objects to reduce the number of function arguments needed.
36   MachineFunction *MF;
37   const Function *Fn;
38   const TargetLowering *TLI;
39   const TargetInstrInfo *TII;
40 
41   /// A map from swifterror value in a basic block to the virtual register it is
42   /// currently represented by.
43   DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
44       VRegDefMap;
45 
46   /// A list of upward exposed vreg uses that need to be satisfied by either a
47   /// copy def or a phi node at the beginning of the basic block representing
48   /// the predecessor(s) swifterror value.
49   DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
50       VRegUpwardsUse;
51 
52   /// A map from instructions that define/use a swifterror value to the virtual
53   /// register that represents that def/use.
54   llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, Register>
55       VRegDefUses;
56 
57   /// The swifterror argument of the current function.
58   const Value *SwiftErrorArg;
59 
60   using SwiftErrorValues = SmallVector<const Value*, 1>;
61   /// A function can only have a single swifterror argument. And if it does
62   /// have a swifterror argument, it must be the first entry in
63   /// SwiftErrorVals.
64   SwiftErrorValues SwiftErrorVals;
65 
66 public:
67   /// Initialize data structures for specified new function.
68   void setFunction(MachineFunction &MF);
69 
70   /// Get the (unique) function argument that was marked swifterror, or nullptr
71   /// if this function has no swifterror args.
72   const Value *getFunctionArg() const {
73     return SwiftErrorArg;
74   }
75 
76   /// Get or create the swifterror value virtual register in
77   /// VRegDefMap for this basic block.
78   Register getOrCreateVReg(const MachineBasicBlock *, const Value *);
79 
80   /// Set the swifterror virtual register in the VRegDefMap for this
81   /// basic block.
82   void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register);
83 
84   /// Get or create the swifterror value virtual register for a def of a
85   /// swifterror by an instruction.
86   Register getOrCreateVRegDefAt(const Instruction *, const MachineBasicBlock *,
87                                 const Value *);
88 
89   /// Get or create the swifterror value virtual register for a use of a
90   /// swifterror by an instruction.
91   Register getOrCreateVRegUseAt(const Instruction *, const MachineBasicBlock *,
92                                 const Value *);
93 
94   /// Create initial definitions of swifterror values in the entry block of the
95   /// current function.
96   bool createEntriesInEntryBlock(DebugLoc DbgLoc);
97 
98   /// Propagate assigned swifterror vregs through a function, synthesizing PHI
99   /// nodes when needed to maintain consistency.
100   void propagateVRegs();
101 
102   void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin,
103                       BasicBlock::const_iterator End);
104 };
105 
106 }
107 
108 #endif
109