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