1327952Sdim//===- MachineSSAUpdater.h - Unstructured SSA Update Tool -------*- C++ -*-===// 2200581Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6200581Srdivacky// 7200581Srdivacky//===----------------------------------------------------------------------===// 8200581Srdivacky// 9200581Srdivacky// This file declares the MachineSSAUpdater class. 10200581Srdivacky// 11200581Srdivacky//===----------------------------------------------------------------------===// 12200581Srdivacky 13200581Srdivacky#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H 14200581Srdivacky#define LLVM_CODEGEN_MACHINESSAUPDATER_H 15200581Srdivacky 16200581Srdivackynamespace llvm { 17200581Srdivacky 18327952Sdimclass MachineBasicBlock; 19327952Sdimclass MachineFunction; 20327952Sdimclass MachineInstr; 21327952Sdimclass MachineOperand; 22327952Sdimclass MachineRegisterInfo; 23327952Sdimclass TargetInstrInfo; 24327952Sdimclass TargetRegisterClass; 25327952Sdimtemplate<typename T> class SmallVectorImpl; 26327952Sdimtemplate<typename T> class SSAUpdaterTraits; 27327952Sdim 28200581Srdivacky/// MachineSSAUpdater - This class updates SSA form for a set of virtual 29200581Srdivacky/// registers defined in multiple blocks. This is used when code duplication 30200581Srdivacky/// or another unstructured transformation wants to rewrite a set of uses of one 31200581Srdivacky/// vreg with uses of a set of vregs. 32200581Srdivackyclass MachineSSAUpdater { 33208599Srdivacky friend class SSAUpdaterTraits<MachineSSAUpdater>; 34207618Srdivacky 35207618Srdivackyprivate: 36200581Srdivacky /// AvailableVals - This keeps track of which value to use on a per-block 37200581Srdivacky /// basis. When we insert PHI nodes, we keep track of them here. 38200581Srdivacky //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy; 39327952Sdim void *AV = nullptr; 40200581Srdivacky 41200581Srdivacky /// VR - Current virtual register whose uses are being updated. 42200581Srdivacky unsigned VR; 43200581Srdivacky 44200581Srdivacky /// VRC - Register class of the current virtual register. 45200581Srdivacky const TargetRegisterClass *VRC; 46200581Srdivacky 47200581Srdivacky /// InsertedPHIs - If this is non-null, the MachineSSAUpdater adds all PHI 48200581Srdivacky /// nodes that it creates to the vector. 49200581Srdivacky SmallVectorImpl<MachineInstr*> *InsertedPHIs; 50200581Srdivacky 51200581Srdivacky const TargetInstrInfo *TII; 52200581Srdivacky MachineRegisterInfo *MRI; 53327952Sdim 54200581Srdivackypublic: 55200581Srdivacky /// MachineSSAUpdater constructor. If InsertedPHIs is specified, it will be 56200581Srdivacky /// filled in with all PHI Nodes created by rewriting. 57200581Srdivacky explicit MachineSSAUpdater(MachineFunction &MF, 58341825Sdim SmallVectorImpl<MachineInstr*> *NewPHI = nullptr); 59327952Sdim MachineSSAUpdater(const MachineSSAUpdater &) = delete; 60327952Sdim MachineSSAUpdater &operator=(const MachineSSAUpdater &) = delete; 61200581Srdivacky ~MachineSSAUpdater(); 62200581Srdivacky 63200581Srdivacky /// Initialize - Reset this object to get ready for a new set of SSA 64200581Srdivacky /// updates. 65200581Srdivacky void Initialize(unsigned V); 66200581Srdivacky 67200581Srdivacky /// AddAvailableValue - Indicate that a rewritten value is available at the 68200581Srdivacky /// end of the specified block with the specified value. 69200581Srdivacky void AddAvailableValue(MachineBasicBlock *BB, unsigned V); 70200581Srdivacky 71200581Srdivacky /// HasValueForBlock - Return true if the MachineSSAUpdater already has a 72200581Srdivacky /// value for the specified block. 73200581Srdivacky bool HasValueForBlock(MachineBasicBlock *BB) const; 74200581Srdivacky 75200581Srdivacky /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is 76200581Srdivacky /// live at the end of the specified block. 77200581Srdivacky unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB); 78200581Srdivacky 79200581Srdivacky /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that 80200581Srdivacky /// is live in the middle of the specified block. 81200581Srdivacky /// 82200581Srdivacky /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one 83200581Srdivacky /// important case: if there is a definition of the rewritten value after the 84200581Srdivacky /// 'use' in BB. Consider code like this: 85200581Srdivacky /// 86200581Srdivacky /// X1 = ... 87200581Srdivacky /// SomeBB: 88200581Srdivacky /// use(X) 89200581Srdivacky /// X2 = ... 90200581Srdivacky /// br Cond, SomeBB, OutBB 91200581Srdivacky /// 92200581Srdivacky /// In this case, there are two values (X1 and X2) added to the AvailableVals 93200581Srdivacky /// set by the client of the rewriter, and those values are both live out of 94200581Srdivacky /// their respective blocks. However, the use of X happens in the *middle* of 95200581Srdivacky /// a block. Because of this, we need to insert a new PHI node in SomeBB to 96200581Srdivacky /// merge the appropriate values, and this value isn't live out of the block. 97200581Srdivacky unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB); 98200581Srdivacky 99200581Srdivacky /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes, 100200581Srdivacky /// which use their value in the corresponding predecessor. Note that this 101200581Srdivacky /// will not work if the use is supposed to be rewritten to a value defined in 102200581Srdivacky /// the same block as the use, but above it. Any 'AddAvailableValue's added 103200581Srdivacky /// for the use's block will be considered to be below it. 104200581Srdivacky void RewriteUse(MachineOperand &U); 105200581Srdivacky 106200581Srdivackyprivate: 107200581Srdivacky unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB); 108200581Srdivacky}; 109200581Srdivacky 110327952Sdim} // end namespace llvm 111200581Srdivacky 112327952Sdim#endif // LLVM_CODEGEN_MACHINESSAUPDATER_H 113