//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include <map>
class LiveVariables : public MachineFunctionPass {
public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveVariables() : MachineFunctionPass((intptr_t)&ID) {}
+
/// VarInfo - This represents the regions where a virtual register is live in
/// the program. We represent this with three different pieces of
/// information: the instruction that uniquely defines the value, the set of
///
BitVector AliveBlocks;
+ /// UsedBlocks - Set of blocks of which this value is actually used. This
+ /// is a bit set which uses the basic block number as an index.
+ BitVector UsedBlocks;
+
/// NumUses - Number of uses of this register across the entire function.
///
unsigned NumUses;
SmallVector<unsigned, 4> *PHIVarInfo;
- /// addRegisterKilled - We have determined MI kills a register. Look for the
- /// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
- /// add a implicit operand if it's not found. Returns true if the operand
- /// exists / is added.
- bool addRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
- bool AddIfNotFound = false);
-
- /// addRegisterDead - We have determined MI defined a register without a use.
- /// Look for the operand that defines it and mark it as IsDead. If
- /// AddIfNotFound is true, add a implicit operand if it's not found. Returns
- /// true if the operand exists / is added.
- bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
- bool AddIfNotFound = false);
+ void addRegisterKills(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+ /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+ /// uses. Pay special attention to the sub-register uses which may come below
+ /// the last use of the whole register.
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
/// not found.
void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
bool AddIfNotFound = false) {
- if (addRegisterKilled(IncomingReg, MI, AddIfNotFound))
+ if (MI->addRegisterKilled(IncomingReg, RegInfo, AddIfNotFound))
getVarInfo(IncomingReg).Kills.push_back(MI);
- }
+ }
/// removeVirtualRegisterKilled - Remove the specified virtual
/// register from the live variable information. Returns true if the
bool Removed = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isUse() && MO.getReg() == reg) {
- MO.unsetIsKill();
+ if (MO.isRegister() && MO.isKill() && MO.getReg() == reg) {
+ MO.setIsKill(false);
Removed = true;
break;
}
/// removeVirtualRegistersKilled - Remove all killed info for the specified
/// instruction.
void removeVirtualRegistersKilled(MachineInstr *MI);
-
+
/// addVirtualRegisterDead - Add information about the fact that the specified
/// register is dead after being used by the specified instruction. If
/// AddIfNotFound is true, add a implicit operand if it's not found.
void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
bool AddIfNotFound = false) {
- if (addRegisterDead(IncomingReg, MI, AddIfNotFound))
+ if (MI->addRegisterDead(IncomingReg, RegInfo, AddIfNotFound))
getVarInfo(IncomingReg).Kills.push_back(MI);
}
bool Removed = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
- MO.unsetIsDead();
+ if (MO.isRegister() && MO.isDef() && MO.getReg() == reg) {
+ MO.setIsDead(false);
Removed = true;
break;
}
/// register.
VarInfo &getVarInfo(unsigned RegIdx);
- void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB);
- void HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB,
+ void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+ MachineBasicBlock *BB);
+ void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+ MachineBasicBlock *BB,
+ std::vector<MachineBasicBlock*> &WorkList);
+ void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
MachineInstr *MI);
};