Skip to content

Commit

Permalink
[VENTUS][fix] Fix insert vmv instruction bug when vmv instruction is …
Browse files Browse the repository at this point in the history
…in JOIN MBB
  • Loading branch information
zhoujing committed Mar 5, 2024
1 parent 292c639 commit d35e6c4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 49 deletions.
66 changes: 18 additions & 48 deletions llvm/lib/Target/RISCV/VentusInsertJoinToVBranch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,14 @@
//
//===----------------------------------------------------------------------===//
//
// In Ventus, if VBranch instructions are generated, we need to insert join
// instructions in both `else` and `then` branch to tell hardware where these
// two branches need to join together
// In ventus, if VBranch instructions are generated, we need to insert setrpc
// and join instructions to tell hardware where branches need to join
//
// we follow the following rules to insert join block and join instruction
//
// 1: Legalize all the return block
// when there are one more return blocks in machine function, there must be
// branches, we need to reduce return blocks number down to 1
// 1.1: If two return blocks have common nearest parent branch, this two blocks
// need to be joined, and we add a hasBeenJoined marker for this parent
// branch
// 1.2: after we complete 1.1 process, there maybe one more return blocks, we
// need to further add join block, we recursively build dominator tree for
// these return blocks, first we find the nearest common dominator branch for
// two return blocks, and then get dominator tree path between dominator
// and each return block, we need to check this path in which whether any
// other branch blocks exists, ideally, the branch block in path should have
// been joined and marked, if not, this path is illegal, these two block can
// not be joined
//
// 2: Insert join instructions
// 2.1: we scan through the MachineBasic blocks and check what blocks to insert
// join instruction, below MBB represents MachineBasic Block
// 2.2: The MBB must have one more predecessors and its nearest dominator must
// be a VBranch
// 2.3: Then we analyze the the predecessor of MBB, if the predecessor
// has single successor, we add a join instruction to the predecessor end,
// other wise, we need to insert a join block between predecessor and MBB
//
// WRANING: Do not use -O(1|2|3) optimization option
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "RISCV.h"
#include "RISCVInstrInfo.h"
#include "RISCVTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/Register.h"
Expand Down Expand Up @@ -231,12 +202,13 @@ bool VentusInsertJoinToVBranch::checkJoinMBB(MachineBasicBlock &MBB) const {
if (MI.getOpcode() != RISCV::VMV_V_X)
continue;

// To be removed vmv.v instruction flag
bool NeedToBeErased = false;
// The number of MBBs where VMV instruction should be inserted into
unsigned NumCandidateMBB = 0;
assert(MI.getOperand(1).isReg() && "unexpected operator");
auto Defines = MR.def_instructions(MI.getOperand(1).getReg());
bool IsInSameBlock = false;

SmallVector<std::pair<MachineBasicBlock *, MachineBasicBlock::iterator>>
MBBAndInsertPosPairs;
for (auto &Def : Defines) {
unsigned Opcode = Def.getOpcode();
// FIXME: Find a better way to handle this in tablegen
Expand All @@ -257,26 +229,24 @@ bool VentusInsertJoinToVBranch::checkJoinMBB(MachineBasicBlock &MBB) const {

// Check if define instruction is in the predecessors or not
for (auto *Pre : MBB.predecessors()) {
bool NeedToBeInsert = false;
MachineBasicBlock::iterator Insert = Pre->begin();
MachineBasicBlock::iterator I = Pre->begin();
for (auto &MI1 : *Pre) {
// Get last register definition
if (&MI1 == &Def) {
Insert = MI1.getIterator();
NeedToBeInsert = true;
NeedToBeErased = true;
}
}
if (NeedToBeInsert) {
Pre->insertAfter(Insert, MF->CloneMachineInstr(&MI));
NeedToBeInsert = false; // Init other predecessor insert flag
// Last register define in Pre MBB
if (&MI1 == &Def)
I = MI1.getIterator();
}
NumCandidateMBB++;
// Only get last vmv instruction definition, break the loop
// FIXME: it worked, but not the best way?
MBBAndInsertPosPairs.push_back({Pre, I});
}
}

if (NeedToBeErased) {
if (NumCandidateMBB >= 2) {
// Means there are more than two blocks need to insert vmv instruction
IsChanged |= true;
MBB.addLiveIn(MCRegister(MI.getOperand(0).getReg()));
for (auto Pair : MBBAndInsertPosPairs)
Pair.first->insertAfter(Pair.second, MF->CloneMachineInstr(&MI));
MI.eraseFromParent();
}
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/VentusRegextInsertion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ bool VentusRegextInsertion::insertRegext(MachineBasicBlock &MBB,
for (unsigned i = 0; i < MI.getNumOperands(); ++i) {
MachineOperand &Op = MI.getOperand(i);
if (!Op.isReg() ||
MI.getDesc().getOperandConstraint(i, MCOI::TIED_TO) != -1)
MI.getDesc().getOperandConstraint(i, MCOI::TIED_TO) != -1 ||
MI.isDebugInstr() || MI.isPseudo())
continue;

uint16_t RegEncodingValue = TRI->getEncodingValue(Op.getReg());
Expand Down

0 comments on commit d35e6c4

Please sign in to comment.