forked from OSchip/llvm-project
105 lines
3.3 KiB
C++
105 lines
3.3 KiB
C++
//===- HexagonGatherPacketize.cpp -----------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// This pass ensures that producer and consumer of VTMP are paired in a bundle.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "gather-packetize"
|
|
|
|
#include "HexagonTargetMachine.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/MachineInstrBundle.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/Debug.h"
|
|
using namespace llvm;
|
|
|
|
cl::opt<bool> EnableGatherPacketize(
|
|
"hexagon-enable-gather-packetize", cl::Hidden, cl::init(true),
|
|
cl::desc("Generate gather packets before packetization"));
|
|
|
|
namespace llvm {
|
|
FunctionPass *createHexagonGatherPacketize();
|
|
void initializeHexagonGatherPacketizePass(PassRegistry &);
|
|
}
|
|
|
|
namespace {
|
|
class HexagonGatherPacketize : public MachineFunctionPass {
|
|
public:
|
|
static char ID;
|
|
HexagonGatherPacketize() : MachineFunctionPass(ID) {
|
|
PassRegistry &Registry = *PassRegistry::getPassRegistry();
|
|
initializeHexagonGatherPacketizePass(Registry);
|
|
}
|
|
|
|
StringRef getPassName() const override {
|
|
return "Hexagon Gather Packetize Code";
|
|
}
|
|
bool runOnMachineFunction(MachineFunction &Fn) override;
|
|
};
|
|
|
|
char HexagonGatherPacketize::ID = 0;
|
|
|
|
static inline bool isVtmpDef(const MachineInstr &MI) {
|
|
for (const MachineOperand &MO : MI.operands())
|
|
if (MO.isReg() && MO.isDef() && MO.isImplicit() &&
|
|
(MO.getReg() == Hexagon::VTMP)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static inline bool isVtmpUse(const MachineInstr &MI) {
|
|
return (MI.mayStore() && (MI.getOperand(2)).isReg() &&
|
|
((MI.getOperand(2)).getReg() == Hexagon::VTMP));
|
|
}
|
|
|
|
bool HexagonGatherPacketize::runOnMachineFunction(MachineFunction &Fn) {
|
|
if (!EnableGatherPacketize)
|
|
return false;
|
|
auto &ST = Fn.getSubtarget<HexagonSubtarget>();
|
|
bool HasV65 = ST.hasV65TOps();
|
|
bool UseHVX = ST.useHVXOps();
|
|
if (!(HasV65 & UseHVX))
|
|
return false;
|
|
|
|
for (auto &MBB : Fn) {
|
|
bool VtmpDef = false;
|
|
MachineBasicBlock::iterator MII, MIE, DefMII;
|
|
for (MII = MBB.begin(), MIE = MBB.end(); MII != MIE; ++MII) {
|
|
MachineInstr &MI = *MII;
|
|
if (VtmpDef) {
|
|
if (!isVtmpUse(MI))
|
|
continue;
|
|
MBB.splice(std::next(DefMII), &MBB, MII);
|
|
finalizeBundle(MBB, DefMII.getInstrIterator(),
|
|
std::next(MII).getInstrIterator());
|
|
VtmpDef = false;
|
|
continue;
|
|
}
|
|
if (!(isVtmpDef(MI)))
|
|
continue;
|
|
VtmpDef = true;
|
|
DefMII = MII;
|
|
}
|
|
assert(!VtmpDef && "VTMP producer and consumer not in same block");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Public Constructor Functions
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
INITIALIZE_PASS(HexagonGatherPacketize, "hexagon-gather-packetize",
|
|
"Hexagon gather packetize Code", false, false)
|
|
|
|
FunctionPass *llvm::createHexagonGatherPacketize() {
|
|
return new HexagonGatherPacketize();
|
|
}
|