mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[Hexagon] Fix some Clang-tidy modernize-use-using and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 309746
This commit is contained in:
parent
22b7cb051b
commit
a8ad1b51ee
@ -1,4 +1,4 @@
|
||||
//===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===//
|
||||
//===- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly ---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,50 +15,50 @@
|
||||
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "MCTargetDesc/HexagonInstPrinter.h"
|
||||
#include "MCTargetDesc/HexagonMCExpr.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDirectives.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSection.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
|
||||
MCInst &MCB, HexagonAsmPrinter &AP);
|
||||
}
|
||||
|
||||
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
|
||||
MCInst &MCB, HexagonAsmPrinter &AP);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
|
||||
@ -78,7 +78,7 @@ inline static unsigned getHexagonRegisterPair(unsigned Reg,
|
||||
|
||||
HexagonAsmPrinter::HexagonAsmPrinter(TargetMachine &TM,
|
||||
std::unique_ptr<MCStreamer> Streamer)
|
||||
: AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr) {}
|
||||
: AsmPrinter(TM, std::move(Streamer)) {}
|
||||
|
||||
void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
@ -106,14 +106,12 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// isBlockOnlyReachableByFallthrough - We need to override this since the
|
||||
// default AsmPrinter does not print labels for any basic block that
|
||||
// is only reachable by a fall through. That works for all cases except
|
||||
// for the case in which the basic block is reachable by a fall through but
|
||||
// through an indirect from a jump table. In this case, the jump table
|
||||
// will contain a label not defined by AsmPrinter.
|
||||
//
|
||||
bool HexagonAsmPrinter::
|
||||
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
|
||||
if (MBB->hasAddressTaken())
|
||||
@ -121,9 +119,7 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
|
||||
return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB);
|
||||
}
|
||||
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
///
|
||||
bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant,
|
||||
const char *ExtraCode,
|
||||
@ -306,35 +302,30 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
break;
|
||||
}
|
||||
|
||||
case Hexagon::A2_tfrf: {
|
||||
case Hexagon::A2_tfrf:
|
||||
Inst.setOpcode(Hexagon::A2_paddif);
|
||||
Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
case Hexagon::A2_tfrt: {
|
||||
case Hexagon::A2_tfrt:
|
||||
Inst.setOpcode(Hexagon::A2_paddit);
|
||||
Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
case Hexagon::A2_tfrfnew: {
|
||||
case Hexagon::A2_tfrfnew:
|
||||
Inst.setOpcode(Hexagon::A2_paddifnew);
|
||||
Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
case Hexagon::A2_tfrtnew: {
|
||||
case Hexagon::A2_tfrtnew:
|
||||
Inst.setOpcode(Hexagon::A2_padditnew);
|
||||
Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(0, OutContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
case Hexagon::A2_zxtb: {
|
||||
case Hexagon::A2_zxtb:
|
||||
Inst.setOpcode(Hexagon::A2_andir);
|
||||
Inst.addOperand(MCOperand::createExpr(MCConstantExpr::create(255, OutContext)));
|
||||
break;
|
||||
}
|
||||
|
||||
// "$dst = CONST64(#$src1)",
|
||||
case Hexagon::CONST64:
|
||||
@ -386,7 +377,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
// 3 register pairs.
|
||||
case Hexagon::M2_vrcmpys_acc_s1: {
|
||||
MCOperand &Rt = Inst.getOperand(3);
|
||||
assert (Rt.isReg() && "Expected register and none was found");
|
||||
assert(Rt.isReg() && "Expected register and none was found");
|
||||
unsigned Reg = RI->getEncodingValue(Rt.getReg());
|
||||
if (Reg & 1)
|
||||
MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
|
||||
@ -397,7 +388,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
}
|
||||
case Hexagon::M2_vrcmpys_s1: {
|
||||
MCOperand &Rt = Inst.getOperand(2);
|
||||
assert (Rt.isReg() && "Expected register and none was found");
|
||||
assert(Rt.isReg() && "Expected register and none was found");
|
||||
unsigned Reg = RI->getEncodingValue(Rt.getReg());
|
||||
if (Reg & 1)
|
||||
MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
|
||||
@ -409,7 +400,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
|
||||
case Hexagon::M2_vrcmpys_s1rp: {
|
||||
MCOperand &Rt = Inst.getOperand(2);
|
||||
assert (Rt.isReg() && "Expected register and none was found");
|
||||
assert(Rt.isReg() && "Expected register and none was found");
|
||||
unsigned Reg = RI->getEncodingValue(Rt.getReg());
|
||||
if (Reg & 1)
|
||||
MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
|
||||
@ -421,7 +412,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
|
||||
case Hexagon::A4_boundscheck: {
|
||||
MCOperand &Rs = Inst.getOperand(1);
|
||||
assert (Rs.isReg() && "Expected register and none was found");
|
||||
assert(Rs.isReg() && "Expected register and none was found");
|
||||
unsigned Reg = RI->getEncodingValue(Rs.getReg());
|
||||
if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
|
||||
MappedInst.setOpcode(Hexagon::A4_boundscheck_hi);
|
||||
@ -430,15 +421,17 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI));
|
||||
return;
|
||||
}
|
||||
|
||||
case Hexagon::PS_call_nr:
|
||||
Inst.setOpcode(Hexagon::J2_call);
|
||||
break;
|
||||
|
||||
case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
|
||||
MCOperand &MO = MappedInst.getOperand(2);
|
||||
int64_t Imm;
|
||||
MCExpr const *Expr = MO.getExpr();
|
||||
bool Success = Expr->evaluateAsAbsolute(Imm);
|
||||
assert (Success && "Expected immediate and none was found");
|
||||
assert(Success && "Expected immediate and none was found");
|
||||
(void)Success;
|
||||
MCInst TmpInst;
|
||||
if (Imm == 0) {
|
||||
@ -458,13 +451,14 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
MappedInst = TmpInst;
|
||||
return;
|
||||
}
|
||||
|
||||
case Hexagon::S5_vasrhrnd_goodsyntax:
|
||||
case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
|
||||
MCOperand &MO2 = MappedInst.getOperand(2);
|
||||
MCExpr const *Expr = MO2.getExpr();
|
||||
int64_t Imm;
|
||||
bool Success = Expr->evaluateAsAbsolute(Imm);
|
||||
assert (Success && "Expected immediate and none was found");
|
||||
assert(Success && "Expected immediate and none was found");
|
||||
(void)Success;
|
||||
MCInst TmpInst;
|
||||
if (Imm == 0) {
|
||||
@ -493,13 +487,14 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
MappedInst = TmpInst;
|
||||
return;
|
||||
}
|
||||
|
||||
// if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd
|
||||
case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
|
||||
MCOperand &MO = Inst.getOperand(2);
|
||||
MCExpr const *Expr = MO.getExpr();
|
||||
int64_t Imm;
|
||||
bool Success = Expr->evaluateAsAbsolute(Imm);
|
||||
assert (Success && "Expected immediate and none was found");
|
||||
assert(Success && "Expected immediate and none was found");
|
||||
(void)Success;
|
||||
MCInst TmpInst;
|
||||
if (Imm == 0) {
|
||||
@ -541,6 +536,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
MappedInst = TmpInst;
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
|
||||
case Hexagon::A2_tfrp: {
|
||||
MCOperand &MO = MappedInst.getOperand(1);
|
||||
@ -566,6 +562,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
: Hexagon::C2_ccombinewf);
|
||||
return;
|
||||
}
|
||||
|
||||
case Hexagon::A2_tfrptnew:
|
||||
case Hexagon::A2_tfrpfnew: {
|
||||
MCOperand &MO = MappedInst.getOperand(2);
|
||||
@ -598,7 +595,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
|
||||
case Hexagon::A2_addsp: {
|
||||
MCOperand &Rt = Inst.getOperand(1);
|
||||
assert (Rt.isReg() && "Expected register and none was found");
|
||||
assert(Rt.isReg() && "Expected register and none was found");
|
||||
unsigned Reg = RI->getEncodingValue(Rt.getReg());
|
||||
if (Reg & 1)
|
||||
MappedInst.setOpcode(Hexagon::A2_addsph);
|
||||
@ -607,11 +604,12 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI));
|
||||
return;
|
||||
}
|
||||
|
||||
case Hexagon::V6_vd0:
|
||||
case Hexagon::V6_vd0_128B: {
|
||||
MCInst TmpInst;
|
||||
assert (Inst.getOperand(0).isReg() &&
|
||||
"Expected register and none was found");
|
||||
assert(Inst.getOperand(0).isReg() &&
|
||||
"Expected register and none was found");
|
||||
|
||||
TmpInst.setOpcode(Hexagon::V6_vxor);
|
||||
TmpInst.addOperand(Inst.getOperand(0));
|
||||
@ -799,10 +797,8 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
|
||||
/// the current output stream.
|
||||
///
|
||||
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
MCInst MCB = HexagonMCInstrInfo::createBundle();
|
||||
const MCInstrInfo &MCII = *Subtarget->getInstrInfo();
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file ----===//
|
||||
//===- HexagonAsmPrinter.h - Print machine code to an Hexagon .s file -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -15,14 +15,20 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONASMPRINTER_H
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstr;
|
||||
class MCInst;
|
||||
class raw_ostream;
|
||||
class TargetMachine;
|
||||
|
||||
class HexagonAsmPrinter : public AsmPrinter {
|
||||
const HexagonSubtarget *Subtarget;
|
||||
const HexagonSubtarget *Subtarget = nullptr;
|
||||
|
||||
public:
|
||||
explicit HexagonAsmPrinter(TargetMachine &TM,
|
||||
@ -45,7 +51,6 @@ namespace llvm {
|
||||
void HexagonProcessInstruction(MCInst &Inst,
|
||||
const MachineInstr &MBB);
|
||||
|
||||
|
||||
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
@ -57,6 +62,6 @@ namespace llvm {
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
};
|
||||
|
||||
} // end of llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONASMPRINTER_H
|
||||
|
@ -14,22 +14,30 @@
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCExpr.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
|
||||
MCInst &MCB, HexagonAsmPrinter &AP);
|
||||
}
|
||||
|
||||
void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
|
||||
MCInst &MCB, HexagonAsmPrinter &AP);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
HexagonAsmPrinter &Printer, bool MustExtend) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass --------===//
|
||||
//===- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,8 +14,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonTargetTransformInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass --------===//
|
||||
//==- HexagonTargetTransformInfo.cpp - Hexagon specific TTI pass -*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -17,16 +17,24 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/CodeGen/BasicTTIImpl.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Loop;
|
||||
class ScalarEvolution;
|
||||
class User;
|
||||
class Value;
|
||||
|
||||
class HexagonTTIImpl : public BasicTTIImplBase<HexagonTTIImpl> {
|
||||
typedef BasicTTIImplBase<HexagonTTIImpl> BaseT;
|
||||
typedef TargetTransformInfo TTI;
|
||||
using BaseT = BasicTTIImplBase<HexagonTTIImpl>;
|
||||
using TTI = TargetTransformInfo;
|
||||
|
||||
friend BaseT;
|
||||
|
||||
const HexagonSubtarget *ST;
|
||||
@ -70,4 +78,4 @@ public:
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETTRANSFORMINFO_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonBaseInfo.h - Top level definitions for Hexagon --*- C++ -*--===//
|
||||
//===- HexagonBaseInfo.h - Top level definitions for Hexagon ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -18,15 +18,12 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
|
||||
|
||||
#include "HexagonDepITypes.h"
|
||||
#include "HexagonMCTargetDesc.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <stdint.h>
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// HexagonII - This namespace holds all of the target specific flags that
|
||||
/// instruction info tracks.
|
||||
///
|
||||
namespace HexagonII {
|
||||
unsigned const TypeCVI_FIRST = TypeCVI_HIST;
|
||||
unsigned const TypeCVI_LAST = TypeCVI_VX_LATE;
|
||||
@ -266,8 +263,8 @@ namespace HexagonII {
|
||||
INST_ICLASS_ALU32_3 = 0xf0000000
|
||||
};
|
||||
|
||||
} // End namespace HexagonII.
|
||||
} // end namespace HexagonII
|
||||
|
||||
} // End namespace llvm.
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
|
||||
|
@ -12,17 +12,20 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonMCChecker.h"
|
||||
|
||||
#include "HexagonBaseInfo.h"
|
||||
|
||||
#include "MCTargetDesc/HexagonMCChecker.h"
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -159,7 +162,7 @@ void HexagonMCChecker::init(MCInst const &MCI) {
|
||||
isPredicateRegister(*SRI))
|
||||
// Some insns produce predicates too late to be used in the same packet.
|
||||
LatePreds.insert(*SRI);
|
||||
else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
|
||||
else if (i == 0 && HexagonMCInstrInfo::getType(MCII, MCI) ==
|
||||
HexagonII::TypeCVI_VM_TMP_LD)
|
||||
// Temporary loads should be used in the same packet, but don't commit
|
||||
// results, so it should be disregarded if another insn changes the same
|
||||
@ -167,7 +170,7 @@ void HexagonMCChecker::init(MCInst const &MCI) {
|
||||
// TODO: relies on the impossibility of a current and a temporary loads
|
||||
// in the same packet.
|
||||
TmpDefs.insert(*SRI);
|
||||
else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
|
||||
else if (i <= 1 && HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
|
||||
// vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
|
||||
// destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
|
||||
Uses.insert(*SRI);
|
||||
@ -223,7 +226,7 @@ void HexagonMCChecker::init(MCInst const &MCI) {
|
||||
// Super-registers cannot use new values.
|
||||
if (MCID.isBranch())
|
||||
NewUses[N] = NewSense::Jmp(
|
||||
llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ);
|
||||
HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ);
|
||||
else
|
||||
NewUses[N] = NewSense::Use(
|
||||
PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
|
||||
@ -268,10 +271,10 @@ bool HexagonMCChecker::checkEndloopBranches() {
|
||||
auto Inner = HexagonMCInstrInfo::isInnerLoop(MCB);
|
||||
if (Inner || HexagonMCInstrInfo::isOuterLoop(MCB)) {
|
||||
reportError(I.getLoc(),
|
||||
llvm::Twine("packet marked with `:endloop") +
|
||||
(Inner ? "0" : "1") + "' " +
|
||||
"cannot contain instructions that modify register " +
|
||||
"`" + llvm::Twine(RI.getName(Hexagon::PC)) + "'");
|
||||
Twine("packet marked with `:endloop") +
|
||||
(Inner ? "0" : "1") + "' " +
|
||||
"cannot contain instructions that modify register " + "`" +
|
||||
Twine(RI.getName(Hexagon::PC)) + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -279,8 +282,7 @@ bool HexagonMCChecker::checkEndloopBranches() {
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool isDuplexAGroup(unsigned Opcode) {
|
||||
static bool isDuplexAGroup(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case Hexagon::SA1_addi:
|
||||
case Hexagon::SA1_addrx:
|
||||
@ -313,7 +315,7 @@ bool isDuplexAGroup(unsigned Opcode) {
|
||||
}
|
||||
}
|
||||
|
||||
bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
|
||||
static bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
|
||||
unsigned Result = 0;
|
||||
unsigned Type = HexagonMCInstrInfo::getType(MCII, ID);
|
||||
if (Type == HexagonII::TypeDUPLEX) {
|
||||
@ -329,7 +331,6 @@ bool isNeitherAnorX(MCInstrInfo const &MCII, MCInst const &ID) {
|
||||
(Type != HexagonII::TypeALU64 || HexagonMCInstrInfo::isFloat(MCII, ID));
|
||||
return Result != 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool HexagonMCChecker::checkAXOK() {
|
||||
MCInst const *HasSoloAXInst = nullptr;
|
||||
@ -344,10 +345,10 @@ bool HexagonMCChecker::checkAXOK() {
|
||||
if (&I != HasSoloAXInst && isNeitherAnorX(MCII, I)) {
|
||||
reportError(
|
||||
HasSoloAXInst->getLoc(),
|
||||
llvm::Twine("Instruction can only be in a packet with ALU or "
|
||||
"non-FPU XTYPE instructions"));
|
||||
Twine("Instruction can only be in a packet with ALU or non-FPU XTYPE "
|
||||
"instructions"));
|
||||
reportError(I.getLoc(),
|
||||
llvm::Twine("Not an ALU or non-FPU XTYPE instruction"));
|
||||
Twine("Not an ALU or non-FPU XTYPE instruction"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -468,7 +469,7 @@ bool HexagonMCChecker::checkRegistersReadOnly() {
|
||||
unsigned Register = Operand.getReg();
|
||||
if (ReadOnly.find(Register) != ReadOnly.end()) {
|
||||
reportError(Inst.getLoc(), "Cannot write to read-only register `" +
|
||||
llvm::Twine(RI.getName(Register)) + "'");
|
||||
Twine(RI.getName(Register)) + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -494,7 +495,7 @@ void HexagonMCChecker::checkRegisterCurDefs() {
|
||||
HexagonMCInstrInfo::getDesc(MCII, I).mayLoad()) {
|
||||
unsigned Register = I.getOperand(0).getReg();
|
||||
if (!registerUsed(Register))
|
||||
reportWarning("Register `" + llvm::Twine(RI.getName(Register)) +
|
||||
reportWarning("Register `" + Twine(RI.getName(Register)) +
|
||||
"' used with `.cur' "
|
||||
"but not used in the same packet");
|
||||
}
|
||||
@ -568,17 +569,16 @@ bool HexagonMCChecker::checkRegisters() {
|
||||
// special case for vhist
|
||||
bool vHistFound = false;
|
||||
for (auto const &HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
|
||||
if (llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
|
||||
if (HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
|
||||
HexagonII::TypeCVI_HIST) {
|
||||
vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Warn on an unused temporary definition.
|
||||
if (vHistFound == false) {
|
||||
reportWarning("register `" + llvm::Twine(RI.getName(R)) +
|
||||
"' used with `.tmp' "
|
||||
"but not used in the same packet");
|
||||
if (!vHistFound) {
|
||||
reportWarning("register `" + Twine(RI.getName(R)) +
|
||||
"' used with `.tmp' but not used in the same packet");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -591,7 +591,7 @@ bool HexagonMCChecker::checkRegisters() {
|
||||
bool HexagonMCChecker::checkSolo() {
|
||||
if (HexagonMCInstrInfo::bundleSize(MCB) > 1)
|
||||
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
|
||||
if (llvm::HexagonMCInstrInfo::isSolo(MCII, I)) {
|
||||
if (HexagonMCInstrInfo::isSolo(MCII, I)) {
|
||||
reportError(I.getLoc(), "Instruction is marked `isSolo' and "
|
||||
"cannot have other instructions in "
|
||||
"the same packet");
|
||||
@ -668,26 +668,26 @@ bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
|
||||
}
|
||||
|
||||
void HexagonMCChecker::reportErrorRegisters(unsigned Register) {
|
||||
reportError("register `" + llvm::Twine(RI.getName(Register)) +
|
||||
reportError("register `" + Twine(RI.getName(Register)) +
|
||||
"' modified more than once");
|
||||
}
|
||||
|
||||
void HexagonMCChecker::reportErrorNewValue(unsigned Register) {
|
||||
reportError("register `" + llvm::Twine(RI.getName(Register)) +
|
||||
reportError("register `" + Twine(RI.getName(Register)) +
|
||||
"' used with `.new' "
|
||||
"but not validly modified in the same packet");
|
||||
}
|
||||
|
||||
void HexagonMCChecker::reportError(llvm::Twine const &Msg) {
|
||||
void HexagonMCChecker::reportError(Twine const &Msg) {
|
||||
reportError(MCB.getLoc(), Msg);
|
||||
}
|
||||
|
||||
void HexagonMCChecker::reportError(SMLoc Loc, llvm::Twine const &Msg) {
|
||||
void HexagonMCChecker::reportError(SMLoc Loc, Twine const &Msg) {
|
||||
if (ReportErrors)
|
||||
Context.reportError(Loc, Msg);
|
||||
}
|
||||
|
||||
void HexagonMCChecker::reportWarning(llvm::Twine const &Msg) {
|
||||
void HexagonMCChecker::reportWarning(Twine const &Msg) {
|
||||
if (ReportErrors) {
|
||||
auto SM = Context.getSourceManager();
|
||||
if (SM)
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===----- HexagonMCChecker.h - Instruction bundle checking ---------------===//
|
||||
//===- HexagonMCChecker.h - Instruction bundle checking ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,17 +12,23 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCCHECKER_H
|
||||
#define HEXAGONMCCHECKER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H
|
||||
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include <queue>
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
#include <set>
|
||||
|
||||
using namespace llvm;
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
class MCOperandInfo;
|
||||
|
||||
class MCContext;
|
||||
class MCInst;
|
||||
class MCInstrInfo;
|
||||
class MCRegisterInfo;
|
||||
class MCSubtargetInfo;
|
||||
|
||||
/// Check for a valid bundle.
|
||||
class HexagonMCChecker {
|
||||
@ -34,13 +40,13 @@ class HexagonMCChecker {
|
||||
bool ReportErrors;
|
||||
|
||||
/// Set of definitions: register #, if predicated, if predicated true.
|
||||
typedef std::pair<unsigned, bool> PredSense;
|
||||
using PredSense = std::pair<unsigned, bool>;
|
||||
static const PredSense Unconditional;
|
||||
typedef std::multiset<PredSense> PredSet;
|
||||
typedef std::multiset<PredSense>::iterator PredSetIterator;
|
||||
using PredSet = std::multiset<PredSense>;
|
||||
using PredSetIterator = std::multiset<PredSense>::iterator;
|
||||
|
||||
typedef llvm::DenseMap<unsigned, PredSet>::iterator DefsIterator;
|
||||
llvm::DenseMap<unsigned, PredSet> Defs;
|
||||
using DefsIterator = DenseMap<unsigned, PredSet>::iterator;
|
||||
DenseMap<unsigned, PredSet> Defs;
|
||||
|
||||
/// Information about how a new-value register is defined or used:
|
||||
/// PredReg = predicate register, 0 if use/def not predicated,
|
||||
@ -52,6 +58,7 @@ class HexagonMCChecker {
|
||||
struct NewSense {
|
||||
unsigned PredReg;
|
||||
bool IsFloat, IsNVJ, Cond;
|
||||
|
||||
// The special-case "constructors":
|
||||
static NewSense Jmp(bool isNVJ) {
|
||||
NewSense NS = {/*PredReg=*/0, /*IsFloat=*/false, /*IsNVJ=*/isNVJ,
|
||||
@ -69,37 +76,38 @@ class HexagonMCChecker {
|
||||
return NS;
|
||||
}
|
||||
};
|
||||
|
||||
/// Set of definitions that produce new register:
|
||||
typedef llvm::SmallVector<NewSense, 2> NewSenseList;
|
||||
typedef llvm::DenseMap<unsigned, NewSenseList>::iterator NewDefsIterator;
|
||||
llvm::DenseMap<unsigned, NewSenseList> NewDefs;
|
||||
using NewSenseList = SmallVector<NewSense, 2>;
|
||||
using NewDefsIterator = DenseMap<unsigned, NewSenseList>::iterator;
|
||||
DenseMap<unsigned, NewSenseList> NewDefs;
|
||||
|
||||
/// Set of weak definitions whose clashes should be enforced selectively.
|
||||
typedef std::set<unsigned>::iterator SoftDefsIterator;
|
||||
using SoftDefsIterator = std::set<unsigned>::iterator;
|
||||
std::set<unsigned> SoftDefs;
|
||||
|
||||
/// Set of temporary definitions not committed to the register file.
|
||||
typedef std::set<unsigned>::iterator TmpDefsIterator;
|
||||
using TmpDefsIterator = std::set<unsigned>::iterator;
|
||||
std::set<unsigned> TmpDefs;
|
||||
|
||||
/// Set of new predicates used.
|
||||
typedef std::set<unsigned>::iterator NewPredsIterator;
|
||||
using NewPredsIterator = std::set<unsigned>::iterator;
|
||||
std::set<unsigned> NewPreds;
|
||||
|
||||
/// Set of predicates defined late.
|
||||
typedef std::multiset<unsigned>::iterator LatePredsIterator;
|
||||
using LatePredsIterator = std::multiset<unsigned>::iterator;
|
||||
std::multiset<unsigned> LatePreds;
|
||||
|
||||
/// Set of uses.
|
||||
typedef std::set<unsigned>::iterator UsesIterator;
|
||||
using UsesIterator = std::set<unsigned>::iterator;
|
||||
std::set<unsigned> Uses;
|
||||
|
||||
/// Set of new values used: new register, if new-value jump.
|
||||
typedef llvm::DenseMap<unsigned, NewSense>::iterator NewUsesIterator;
|
||||
llvm::DenseMap<unsigned, NewSense> NewUses;
|
||||
using NewUsesIterator = DenseMap<unsigned, NewSense>::iterator;
|
||||
DenseMap<unsigned, NewSense> NewUses;
|
||||
|
||||
/// Pre-defined set of read-only registers.
|
||||
typedef std::set<unsigned>::iterator ReadOnlyIterator;
|
||||
using ReadOnlyIterator = std::set<unsigned>::iterator;
|
||||
std::set<unsigned> ReadOnly;
|
||||
|
||||
void init();
|
||||
@ -126,11 +134,12 @@ class HexagonMCChecker {
|
||||
bool isPredicateRegister(unsigned R) const {
|
||||
return (Hexagon::P0 == R || Hexagon::P1 == R || Hexagon::P2 == R ||
|
||||
Hexagon::P3 == R);
|
||||
};
|
||||
}
|
||||
|
||||
bool isLoopRegister(unsigned R) const {
|
||||
return (Hexagon::SA0 == R || Hexagon::LC0 == R || Hexagon::SA1 == R ||
|
||||
Hexagon::LC1 == R);
|
||||
};
|
||||
}
|
||||
|
||||
bool hasValidNewValueDef(const NewSense &Use, const NewSenseList &Defs) const;
|
||||
|
||||
@ -142,11 +151,11 @@ public:
|
||||
bool check(bool FullCheck = true);
|
||||
void reportErrorRegisters(unsigned Register);
|
||||
void reportErrorNewValue(unsigned Register);
|
||||
void reportError(SMLoc Loc, llvm::Twine const &Msg);
|
||||
void reportError(llvm::Twine const &Msg);
|
||||
void reportWarning(llvm::Twine const &Msg);
|
||||
void reportError(SMLoc Loc, Twine const &Msg);
|
||||
void reportError(Twine const &Msg);
|
||||
void reportWarning(Twine const &Msg);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // HEXAGONMCCHECKER_H
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===//
|
||||
//===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,19 +11,29 @@
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonFixupKinds.h"
|
||||
#include "MCTargetDesc/HexagonMCExpr.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#define DEBUG_TYPE "mccodeemitter"
|
||||
|
||||
@ -89,7 +99,6 @@ void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
*Addend += HEXAGON_INSTR_SIZE;
|
||||
++*CurrentIndex;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static bool RegisterMatches(unsigned Consumer, unsigned Producer,
|
||||
@ -158,18 +167,16 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction(
|
||||
++MCNumEmitted;
|
||||
}
|
||||
|
||||
namespace {
|
||||
LLVM_ATTRIBUTE_NORETURN
|
||||
void raise_relocation_error(unsigned bits, unsigned kind) {
|
||||
static void raise_relocation_error(unsigned bits, unsigned kind) {
|
||||
std::string Text;
|
||||
{
|
||||
llvm::raw_string_ostream Stream(Text);
|
||||
raw_string_ostream Stream(Text);
|
||||
Stream << "Unrecognized relocation combination bits: " << bits
|
||||
<< " kind: " << kind;
|
||||
}
|
||||
report_fatal_error(Text);
|
||||
}
|
||||
}
|
||||
|
||||
/// getFixupNoBits - Some insns are not extended and thus have no
|
||||
/// bits. These cases require a more brute force method for determining
|
||||
@ -178,7 +185,7 @@ Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits(
|
||||
MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO,
|
||||
const MCSymbolRefExpr::VariantKind kind) const {
|
||||
const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
|
||||
unsigned insnType = llvm::HexagonMCInstrInfo::getType(MCII, MI);
|
||||
unsigned insnType = HexagonMCInstrInfo::getType(MCII, MI);
|
||||
|
||||
if (insnType == HexagonII::TypeEXTENDER) {
|
||||
switch (kind) {
|
||||
@ -303,34 +310,34 @@ Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits(
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
extern const MCInstrDesc HexagonInsts[];
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool isPCRel (unsigned Kind) {
|
||||
switch(Kind){
|
||||
case fixup_Hexagon_B22_PCREL:
|
||||
case fixup_Hexagon_B15_PCREL:
|
||||
case fixup_Hexagon_B7_PCREL:
|
||||
case fixup_Hexagon_B13_PCREL:
|
||||
case fixup_Hexagon_B9_PCREL:
|
||||
case fixup_Hexagon_B32_PCREL_X:
|
||||
case fixup_Hexagon_B22_PCREL_X:
|
||||
case fixup_Hexagon_B15_PCREL_X:
|
||||
case fixup_Hexagon_B13_PCREL_X:
|
||||
case fixup_Hexagon_B9_PCREL_X:
|
||||
case fixup_Hexagon_B7_PCREL_X:
|
||||
case fixup_Hexagon_32_PCREL:
|
||||
case fixup_Hexagon_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_GD_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_LD_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_GD_PLT_B22_PCREL_X:
|
||||
case fixup_Hexagon_LD_PLT_B22_PCREL_X:
|
||||
case fixup_Hexagon_6_PCREL_X:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
extern const MCInstrDesc HexagonInsts[];
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
static bool isPCRel (unsigned Kind) {
|
||||
switch(Kind){
|
||||
case fixup_Hexagon_B22_PCREL:
|
||||
case fixup_Hexagon_B15_PCREL:
|
||||
case fixup_Hexagon_B7_PCREL:
|
||||
case fixup_Hexagon_B13_PCREL:
|
||||
case fixup_Hexagon_B9_PCREL:
|
||||
case fixup_Hexagon_B32_PCREL_X:
|
||||
case fixup_Hexagon_B22_PCREL_X:
|
||||
case fixup_Hexagon_B15_PCREL_X:
|
||||
case fixup_Hexagon_B13_PCREL_X:
|
||||
case fixup_Hexagon_B9_PCREL_X:
|
||||
case fixup_Hexagon_B7_PCREL_X:
|
||||
case fixup_Hexagon_32_PCREL:
|
||||
case fixup_Hexagon_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_GD_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_LD_PLT_B22_PCREL:
|
||||
case fixup_Hexagon_GD_PLT_B22_PCREL_X:
|
||||
case fixup_Hexagon_LD_PLT_B22_PCREL_X:
|
||||
case fixup_Hexagon_6_PCREL_X:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,7 +346,6 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
|
||||
const MCExpr *ME,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const
|
||||
|
||||
{
|
||||
if (isa<HexagonMCExpr>(ME))
|
||||
ME = &HexagonMCInstrInfo::getExpr(*ME);
|
||||
@ -476,7 +482,7 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
|
||||
}
|
||||
} else
|
||||
switch (kind) {
|
||||
case MCSymbolRefExpr::VK_None: {
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
if (HexagonMCInstrInfo::s27_2_reloc(*MO.getExpr()))
|
||||
FixupKind = Hexagon::fixup_Hexagon_27_REG;
|
||||
else
|
||||
@ -505,7 +511,6 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
|
||||
} else
|
||||
raise_relocation_error(bits, kind);
|
||||
break;
|
||||
}
|
||||
case MCSymbolRefExpr::VK_DTPREL:
|
||||
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
|
||||
break;
|
||||
@ -787,7 +792,7 @@ HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
|
||||
if (MO.isReg()) {
|
||||
unsigned Reg = MO.getReg();
|
||||
if (HexagonMCInstrInfo::isSubInstruction(MI) ||
|
||||
llvm::HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCJ)
|
||||
HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCJ)
|
||||
return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg);
|
||||
return MCT.getRegisterInfo()->getEncodingValue(Reg);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- HexagonMCCodeEmitter.h - Hexagon Target Descriptions ----*- C++ -*-===//
|
||||
//===- HexagonMCCodeEmitter.h - Hexagon Target Descriptions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,20 +12,26 @@
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCCODEEMITTER_H
|
||||
#define HEXAGONMCCODEEMITTER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCODEEMITTER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCODEEMITTER_H
|
||||
|
||||
#include "MCTargetDesc/HexagonFixupKinds.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCContext;
|
||||
class MCInst;
|
||||
class MCInstrInfo;
|
||||
class MCOperand;
|
||||
class MCSubtargetInfo;
|
||||
class raw_ostream;
|
||||
|
||||
class HexagonMCCodeEmitter : public MCCodeEmitter {
|
||||
MCContext &MCT;
|
||||
MCInstrInfo const &MCII;
|
||||
@ -73,8 +79,8 @@ private:
|
||||
uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
|
||||
void verifyInstructionPredicates(const MCInst &MI,
|
||||
uint64_t AvailableFeatures) const;
|
||||
}; // class HexagonMCCodeEmitter
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
#endif /* HEXAGONMCCODEEMITTER_H */
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCODEEMITTER_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===----- HexagonMCDuplexInfo.cpp - Instruction bundle checking ----------===//
|
||||
//===- HexagonMCDuplexInfo.cpp - Instruction bundle checking --------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,15 +11,22 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace Hexagon;
|
||||
|
@ -11,17 +11,27 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonMCInstrInfo.h"
|
||||
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonBaseInfo.h"
|
||||
#include "HexagonMCChecker.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCChecker.h"
|
||||
#include "MCTargetDesc/HexagonMCExpr.h"
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace llvm {
|
||||
using namespace llvm;
|
||||
|
||||
Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
|
||||
MCInst const &Inst)
|
||||
@ -231,6 +241,7 @@ MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
|
||||
|
||||
unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
|
||||
using namespace Hexagon;
|
||||
|
||||
switch (Reg) {
|
||||
default:
|
||||
llvm_unreachable("unknown duplex register");
|
||||
@ -769,11 +780,11 @@ bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {
|
||||
}
|
||||
void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
|
||||
HexagonMCExpr &HExpr =
|
||||
const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr));
|
||||
const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
|
||||
HExpr.setS27_2_reloc(Val);
|
||||
}
|
||||
bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) {
|
||||
HexagonMCExpr const *HExpr = llvm::dyn_cast<HexagonMCExpr>(&Expr);
|
||||
HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
|
||||
if (!HExpr)
|
||||
return false;
|
||||
return HExpr->s27_2_reloc();
|
||||
@ -848,4 +859,3 @@ unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
|
||||
return 0x1;
|
||||
return 0;
|
||||
}
|
||||
} // namespace llvm
|
||||
|
@ -14,24 +14,39 @@
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
|
||||
|
||||
#include "HexagonMCExpr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class HexagonMCChecker;
|
||||
class MCContext;
|
||||
class MCExpr;
|
||||
class MCInstrDesc;
|
||||
class MCInstrInfo;
|
||||
class MCSubtargetInfo;
|
||||
|
||||
namespace HexagonII {
|
||||
|
||||
enum class MemAccessSize;
|
||||
}
|
||||
|
||||
} // end namespace HexagonII
|
||||
|
||||
class DuplexCandidate {
|
||||
public:
|
||||
unsigned packetIndexI, packetIndexJ, iClass;
|
||||
|
||||
DuplexCandidate(unsigned i, unsigned j, unsigned iClass)
|
||||
: packetIndexI(i), packetIndexJ(j), iClass(iClass) {}
|
||||
};
|
||||
|
||||
namespace Hexagon {
|
||||
|
||||
class PacketIterator {
|
||||
MCInstrInfo const &MCII;
|
||||
MCInst::const_iterator BundleCurrent;
|
||||
@ -42,6 +57,7 @@ class PacketIterator {
|
||||
public:
|
||||
PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst);
|
||||
PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst, std::nullptr_t);
|
||||
|
||||
PacketIterator &operator++();
|
||||
MCInst const &operator*() const;
|
||||
bool operator==(PacketIterator const &Other) const;
|
||||
@ -49,8 +65,11 @@ public:
|
||||
return !(*this == Other);
|
||||
}
|
||||
};
|
||||
} // namespace Hexagon
|
||||
|
||||
} // end namespace Hexagon
|
||||
|
||||
namespace HexagonMCInstrInfo {
|
||||
|
||||
size_t const innerLoopOffset = 0;
|
||||
int64_t const innerLoopMask = 1 << innerLoopOffset;
|
||||
|
||||
@ -303,7 +322,9 @@ unsigned SubregisterBit(unsigned Consumer, unsigned Producer,
|
||||
// Attempt to find and replace compound pairs
|
||||
void tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
|
||||
MCContext &Context, MCInst &MCI);
|
||||
} // namespace HexagonMCInstrInfo
|
||||
} // namespace llvm
|
||||
|
||||
} // end namespace HexagonMCInstrInfo
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
|
||||
|
@ -17,10 +17,14 @@
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "MCTargetDesc/HexagonShuffler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -128,7 +132,6 @@ bool
|
||||
llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI, MCInst &MCB,
|
||||
SmallVector<DuplexCandidate, 8> possibleDuplexes) {
|
||||
|
||||
if (DisableShuffle)
|
||||
return false;
|
||||
|
||||
@ -165,7 +168,7 @@ llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
|
||||
break;
|
||||
}
|
||||
|
||||
if (doneShuffling == false) {
|
||||
if (!doneShuffling) {
|
||||
HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
|
||||
doneShuffling = MCS.reshuffleTo(MCB); // shuffle
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//=-- HexagonMCShuffler.h ---------------------------------------------------=//
|
||||
//===- HexagonMCShuffler.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,13 +12,20 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCSHUFFLER_H
|
||||
#define HEXAGONMCSHUFFLER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCSHUFFLER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCSHUFFLER_H
|
||||
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonShuffler.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCContext;
|
||||
class MCInst;
|
||||
class MCInstrInfo;
|
||||
class MCSubtargetInfo;
|
||||
|
||||
// Insn bundle shuffler.
|
||||
class HexagonMCShuffler : public HexagonShuffler {
|
||||
public:
|
||||
@ -26,16 +33,18 @@ public:
|
||||
MCSubtargetInfo const &STI, MCInst &MCB)
|
||||
: HexagonShuffler(Context, Fatal, MCII, STI) {
|
||||
init(MCB);
|
||||
};
|
||||
}
|
||||
|
||||
HexagonMCShuffler(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI, MCInst &MCB,
|
||||
MCInst const &AddMI, bool InsertAtFront)
|
||||
: HexagonShuffler(Context, Fatal, MCII, STI) {
|
||||
init(MCB, AddMI, InsertAtFront);
|
||||
};
|
||||
}
|
||||
|
||||
// Copy reordered bundle to another.
|
||||
void copyTo(MCInst &MCB);
|
||||
|
||||
// Reorder and copy result to another.
|
||||
bool reshuffleTo(MCInst &MCB);
|
||||
|
||||
@ -46,13 +55,14 @@ private:
|
||||
|
||||
// Invocation of the shuffler.
|
||||
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI, MCInst &);
|
||||
MCSubtargetInfo const &STI, MCInst &MCB);
|
||||
bool HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI, MCInst &, MCInst const &,
|
||||
int);
|
||||
MCSubtargetInfo const &STI, MCInst &MCB,
|
||||
MCInst const &AddMI, int fixupCount);
|
||||
bool HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
|
||||
MCSubtargetInfo const &STI, MCInst &,
|
||||
SmallVector<DuplexCandidate, 8>);
|
||||
} // namespace llvm
|
||||
MCSubtargetInfo const &STI, MCInst &MCB,
|
||||
SmallVector<DuplexCandidate, 8> possibleDuplexes);
|
||||
|
||||
#endif // HEXAGONMCSHUFFLER_H
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCSHUFFLER_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===----- HexagonShuffler.cpp - Instruction bundle shuffling -------------===//
|
||||
//===- HexagonShuffler.cpp - Instruction bundle shuffling -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -14,32 +14,39 @@
|
||||
|
||||
#define DEBUG_TYPE "hexagon-shuffle"
|
||||
|
||||
#include "HexagonShuffler.h"
|
||||
#include "MCTargetDesc/HexagonShuffler.h"
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
// Insn shuffling priority.
|
||||
class HexagonBid {
|
||||
// The priority is directly proportional to how restricted the insn is based
|
||||
// on its flexibility to run on the available slots. So, the fewer slots it
|
||||
// may run on, the higher its priority.
|
||||
enum { MAX = 360360 }; // LCD of 1/2, 1/3, 1/4,... 1/15.
|
||||
unsigned Bid;
|
||||
unsigned Bid = 0;
|
||||
|
||||
public:
|
||||
HexagonBid() : Bid(0) {}
|
||||
HexagonBid() = default;
|
||||
HexagonBid(unsigned B) { Bid = B ? MAX / countPopulation(B) : 0; }
|
||||
|
||||
// Check if the insn priority is overflowed.
|
||||
@ -58,7 +65,7 @@ class HexagonUnitAuction {
|
||||
unsigned isSold : HEXAGON_PACKET_SIZE;
|
||||
|
||||
public:
|
||||
HexagonUnitAuction(unsigned cs = 0) : isSold(cs){};
|
||||
HexagonUnitAuction(unsigned cs = 0) : isSold(cs) {}
|
||||
|
||||
// Allocate slots.
|
||||
bool bid(unsigned B) {
|
||||
@ -77,6 +84,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
unsigned HexagonResource::setWeight(unsigned s) {
|
||||
@ -149,10 +157,9 @@ struct CVIUnits {
|
||||
unsigned Units;
|
||||
unsigned Lanes;
|
||||
};
|
||||
typedef SmallVector<struct CVIUnits, 8> HVXInstsT;
|
||||
using HVXInstsT = SmallVector<struct CVIUnits, 8>;
|
||||
|
||||
static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
|
||||
|
||||
{
|
||||
for (unsigned i = 1; i < Lanes; ++i)
|
||||
startBit = (startBit << 1) | startBit;
|
||||
@ -160,9 +167,7 @@ static unsigned makeAllBits(unsigned startBit, unsigned Lanes)
|
||||
}
|
||||
|
||||
static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
|
||||
unsigned usedUnits)
|
||||
|
||||
{
|
||||
unsigned usedUnits) {
|
||||
if (startIdx < hvxInsts.size()) {
|
||||
if (!hvxInsts[startIdx].Units)
|
||||
return checkHVXPipes(hvxInsts, startIdx + 1, usedUnits);
|
||||
@ -353,21 +358,21 @@ bool HexagonShuffler::check() {
|
||||
// Check if the packet is legal.
|
||||
if ((load0 > 1 || store0 > 1) ||
|
||||
(duplex > 1 || (duplex && memory))) {
|
||||
reportError(llvm::Twine("invalid instruction packet"));
|
||||
reportError(Twine("invalid instruction packet"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jump1 && jumps > 1) {
|
||||
// Error if single branch with another branch.
|
||||
reportError(llvm::Twine("too many branches in packet"));
|
||||
reportError(Twine("too many branches in packet"));
|
||||
return false;
|
||||
}
|
||||
if ((nvstores || memops) && stores > 1) {
|
||||
reportError(llvm::Twine("slot 0 instruction does not allow slot 1 store"));
|
||||
reportError(Twine("slot 0 instruction does not allow slot 1 store"));
|
||||
return false;
|
||||
}
|
||||
if (deallocs && stores) {
|
||||
reportError(llvm::Twine("slot 0 instruction does not allow slot 1 store"));
|
||||
reportError(Twine("slot 0 instruction does not allow slot 1 store"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -409,8 +414,7 @@ bool HexagonShuffler::check() {
|
||||
else if (stores > 1) {
|
||||
if (slotLoadStore < slotLastLoadStore) {
|
||||
// Error if no more slots available for stores.
|
||||
reportError(
|
||||
llvm::Twine("invalid instruction packet: too many stores"));
|
||||
reportError(Twine("invalid instruction packet: too many stores"));
|
||||
return false;
|
||||
}
|
||||
// Pin the store to the highest slot available to it.
|
||||
@ -421,7 +425,7 @@ bool HexagonShuffler::check() {
|
||||
}
|
||||
if (store1 && stores > 1) {
|
||||
// Error if a single store with another store.
|
||||
reportError(llvm::Twine("invalid instruction packet: too many stores"));
|
||||
reportError(Twine("invalid instruction packet: too many stores"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -432,7 +436,7 @@ bool HexagonShuffler::check() {
|
||||
|
||||
if (!ISJ->Core.getUnits()) {
|
||||
// Error if insn may not be executed in any slot.
|
||||
reportError(llvm::Twine("invalid instruction packet: out of slots"));
|
||||
reportError(Twine("invalid instruction packet: out of slots"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -441,7 +445,7 @@ bool HexagonShuffler::check() {
|
||||
bool validateSlots = true;
|
||||
if (jumps > 1) {
|
||||
if (foundBranches.size() > 2) {
|
||||
reportError(llvm::Twine("too many branches in packet"));
|
||||
reportError(Twine("too many branches in packet"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -465,7 +469,7 @@ bool HexagonShuffler::check() {
|
||||
|
||||
// see if things ok with that instruction being pinned to slot "slotJump"
|
||||
bool bFail = false;
|
||||
for (iterator I = begin(); I != end() && bFail != true; ++I)
|
||||
for (iterator I = begin(); I != end() && !bFail; ++I)
|
||||
if (!AuctionCore.bid(I->Core.getUnits()))
|
||||
bFail = true;
|
||||
|
||||
@ -477,14 +481,13 @@ bool HexagonShuffler::check() {
|
||||
// restore original values
|
||||
Packet = PacketSave;
|
||||
}
|
||||
if (validateSlots == true) {
|
||||
reportError(llvm::Twine("invalid instruction packet: out of slots"));
|
||||
if (validateSlots) {
|
||||
reportError(Twine("invalid instruction packet: out of slots"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (jumps <= 1 && bOnlySlot3 == false && pSlot3Cnt == 1 &&
|
||||
slot3ISJ != end()) {
|
||||
if (jumps <= 1 && !bOnlySlot3 && pSlot3Cnt == 1 && slot3ISJ != end()) {
|
||||
validateSlots = true;
|
||||
// save off slot mask of instruction marked with A_PREFER_SLOT3
|
||||
// and then pin it to slot #3
|
||||
@ -496,7 +499,7 @@ bool HexagonShuffler::check() {
|
||||
|
||||
// see if things ok with that instruction being pinned to slot #3
|
||||
bool bFail = false;
|
||||
for (iterator I = begin(); I != end() && bFail != true; ++I)
|
||||
for (iterator I = begin(); I != end() && !bFail; ++I)
|
||||
if (!AuctionCore.bid(I->Core.getUnits()))
|
||||
bFail = true;
|
||||
|
||||
@ -520,7 +523,7 @@ bool HexagonShuffler::check() {
|
||||
|
||||
for (iterator I = begin(); I != end(); ++I)
|
||||
if (!AuctionCore.bid(I->Core.getUnits())) {
|
||||
reportError(llvm::Twine("invalid instruction packet: slot error"));
|
||||
reportError(Twine("invalid instruction packet: slot error"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -541,9 +544,9 @@ bool HexagonShuffler::check() {
|
||||
if (hvxInsts.size() > 0) {
|
||||
unsigned startIdx, usedUnits;
|
||||
startIdx = usedUnits = 0x0;
|
||||
if (checkHVXPipes(hvxInsts, startIdx, usedUnits) == false) {
|
||||
if (!checkHVXPipes(hvxInsts, startIdx, usedUnits)) {
|
||||
// too many pipes used to be valid
|
||||
reportError(llvm::Twine("invalid instruction packet: slot error"));
|
||||
reportError(Twine("invalid instruction packet: slot error"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -555,7 +558,7 @@ bool HexagonShuffler::shuffle() {
|
||||
if (size() > HEXAGON_PACKET_SIZE) {
|
||||
// Ignore a packet with with more than what a packet can hold
|
||||
// or with compound or duplex insns for now.
|
||||
reportError(llvm::Twine("invalid instruction packet"));
|
||||
reportError(Twine("invalid instruction packet"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -600,7 +603,7 @@ bool HexagonShuffler::shuffle() {
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void HexagonShuffler::reportError(llvm::Twine const &Msg) {
|
||||
void HexagonShuffler::reportError(Twine const &Msg) {
|
||||
if (ReportErrors)
|
||||
Context.reportError(Loc, Msg);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===----- HexagonShuffler.h - Instruction bundle shuffling ---------------===//
|
||||
//===- HexagonShuffler.h - Instruction bundle shuffling ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,19 +12,25 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONSHUFFLER_H
|
||||
#define HEXAGONSHUFFLER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCContext;
|
||||
class MCInst;
|
||||
class MCInstrInfo;
|
||||
class MCSubtargetInfo;
|
||||
|
||||
// Insn resources.
|
||||
class HexagonResource {
|
||||
// Mask of the slots or units that may execute the insn and
|
||||
@ -32,32 +38,34 @@ class HexagonResource {
|
||||
unsigned Slots, Weight;
|
||||
|
||||
public:
|
||||
HexagonResource(unsigned s) { setUnits(s); };
|
||||
HexagonResource(unsigned s) { setUnits(s); }
|
||||
|
||||
void setUnits(unsigned s) {
|
||||
Slots = s & ((1u << HEXAGON_PACKET_SIZE) - 1);
|
||||
setWeight(s);
|
||||
};
|
||||
}
|
||||
|
||||
unsigned setWeight(unsigned s);
|
||||
|
||||
unsigned getUnits() const { return (Slots); };
|
||||
unsigned getWeight() const { return (Weight); };
|
||||
unsigned getUnits() const { return (Slots); }
|
||||
unsigned getWeight() const { return (Weight); }
|
||||
|
||||
// Check if the resources are in ascending slot order.
|
||||
static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
|
||||
return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
|
||||
};
|
||||
}
|
||||
|
||||
// Check if the resources are in ascending weight order.
|
||||
static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
|
||||
return (A.getWeight() < B.getWeight());
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// HVX insn resources.
|
||||
class HexagonCVIResource : public HexagonResource {
|
||||
public:
|
||||
typedef std::pair<unsigned, unsigned> UnitsAndLanes;
|
||||
typedef llvm::DenseMap<unsigned, UnitsAndLanes> TypeUnitsAndLanes;
|
||||
using UnitsAndLanes = std::pair<unsigned, unsigned>;
|
||||
using TypeUnitsAndLanes = DenseMap<unsigned, UnitsAndLanes>;
|
||||
|
||||
private:
|
||||
// Available HVX slots.
|
||||
@ -78,19 +86,20 @@ private:
|
||||
// Flag whether the HVX resources are valid.
|
||||
bool Valid;
|
||||
|
||||
void setLanes(unsigned l) { Lanes = l; };
|
||||
void setLoad(bool f = true) { Load = f; };
|
||||
void setStore(bool f = true) { Store = f; };
|
||||
void setLanes(unsigned l) { Lanes = l; }
|
||||
void setLoad(bool f = true) { Load = f; }
|
||||
void setStore(bool f = true) { Store = f; }
|
||||
|
||||
public:
|
||||
HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
|
||||
unsigned s, MCInst const *id);
|
||||
|
||||
static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
|
||||
|
||||
bool isValid() const { return Valid; };
|
||||
unsigned getLanes() const { return Lanes; };
|
||||
bool mayLoad() const { return Load; };
|
||||
bool mayStore() const { return Store; };
|
||||
bool isValid() const { return Valid; }
|
||||
unsigned getLanes() const { return Lanes; }
|
||||
bool mayLoad() const { return Load; }
|
||||
bool mayStore() const { return Store; }
|
||||
};
|
||||
|
||||
// Handle to an insn used by the shuffling algorithm.
|
||||
@ -106,30 +115,31 @@ public:
|
||||
HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
|
||||
MCInstrInfo const &MCII, MCInst const *id,
|
||||
MCInst const *Extender, unsigned s)
|
||||
: ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {};
|
||||
|
||||
MCInst const &getDesc() const { return *ID; };
|
||||
: ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {}
|
||||
|
||||
MCInst const &getDesc() const { return *ID; }
|
||||
MCInst const *getExtender() const { return Extender; }
|
||||
|
||||
// Check if the handles are in ascending order for shuffling purposes.
|
||||
bool operator<(const HexagonInstr &B) const {
|
||||
return (HexagonResource::lessWeight(B.Core, Core));
|
||||
};
|
||||
}
|
||||
|
||||
// Check if the handles are in ascending order by core slots.
|
||||
static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
|
||||
return (HexagonResource::lessUnits(A.Core, B.Core));
|
||||
};
|
||||
}
|
||||
|
||||
// Check if the handles are in ascending order by HVX slots.
|
||||
static bool lessCVI(const HexagonInstr &A, const HexagonInstr &B) {
|
||||
return (HexagonResource::lessUnits(A.CVI, B.CVI));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Bundle shuffler.
|
||||
class HexagonShuffler {
|
||||
typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
|
||||
HexagonPacket;
|
||||
using HexagonPacket =
|
||||
SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>;
|
||||
|
||||
// Insn handles in a bundle.
|
||||
HexagonPacket Packet;
|
||||
@ -146,7 +156,7 @@ protected:
|
||||
bool ReportErrors;
|
||||
|
||||
public:
|
||||
typedef HexagonPacket::iterator iterator;
|
||||
using iterator = HexagonPacket::iterator;
|
||||
|
||||
HexagonShuffler(MCContext &Context, bool ReportErrors,
|
||||
MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
|
||||
@ -158,17 +168,18 @@ public:
|
||||
// Reorder the insn handles in the bundle.
|
||||
bool shuffle();
|
||||
|
||||
unsigned size() const { return (Packet.size()); };
|
||||
unsigned size() const { return (Packet.size()); }
|
||||
|
||||
iterator begin() { return (Packet.begin()); };
|
||||
iterator end() { return (Packet.end()); };
|
||||
iterator begin() { return (Packet.begin()); }
|
||||
iterator end() { return (Packet.end()); }
|
||||
|
||||
// Add insn handle to the bundle .
|
||||
void append(MCInst const &ID, MCInst const *Extender, unsigned S);
|
||||
|
||||
// Return the error code for the last check or shuffling of the bundle.
|
||||
void reportError(llvm::Twine const &Msg);
|
||||
void reportError(Twine const &Msg);
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // HEXAGONSHUFFLER_H
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONSHUFFLER_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFCopy.cpp ------------------------------------------------------===//
|
||||
//===- RDFCopy.cpp --------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -8,17 +8,27 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// RDF-based copy propagation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "RDFCopy.h"
|
||||
#include "RDFGraph.h"
|
||||
#include "RDFLiveness.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace rdf;
|
||||
|
||||
@ -50,13 +60,11 @@ bool CopyPropagation::interpretAsCopy(const MachineInstr *MI, EqualityMap &EM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CopyPropagation::recordCopy(NodeAddr<StmtNode*> SA, EqualityMap &EM) {
|
||||
CopyMap.insert(std::make_pair(SA.Id, EM));
|
||||
Copies.push_back(SA.Id);
|
||||
}
|
||||
|
||||
|
||||
bool CopyPropagation::scanBlock(MachineBasicBlock *B) {
|
||||
bool Changed = false;
|
||||
NodeAddr<BlockNode*> BA = DFG.findBlock(B);
|
||||
@ -77,7 +85,6 @@ bool CopyPropagation::scanBlock(MachineBasicBlock *B) {
|
||||
return Changed;
|
||||
}
|
||||
|
||||
|
||||
NodeId CopyPropagation::getLocalReachingDef(RegisterRef RefRR,
|
||||
NodeAddr<InstrNode*> IA) {
|
||||
NodeAddr<RefNode*> RA = L.getNearestAliasedRef(RefRR, IA);
|
||||
@ -91,7 +98,6 @@ NodeId CopyPropagation::getLocalReachingDef(RegisterRef RefRR,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool CopyPropagation::run() {
|
||||
scanBlock(&DFG.getMF().front());
|
||||
|
||||
@ -205,4 +211,3 @@ bool CopyPropagation::run() {
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFCopy.h ----------------------------------------------*- C++ -*-===//
|
||||
//===- RDFCopy.h ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,22 +12,22 @@
|
||||
|
||||
#include "RDFGraph.h"
|
||||
#include "RDFLiveness.h"
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineBasicBlock;
|
||||
class MachineDominatorTree;
|
||||
class MachineInstr;
|
||||
class MachineBasicBlock;
|
||||
class MachineDominatorTree;
|
||||
class MachineInstr;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
struct CopyPropagation {
|
||||
CopyPropagation(DataFlowGraph &dfg) : MDT(dfg.getDT()), DFG(dfg),
|
||||
L(dfg.getMF().getRegInfo(), dfg), Trace(false) {}
|
||||
L(dfg.getMF().getRegInfo(), dfg) {}
|
||||
|
||||
virtual ~CopyPropagation() = default;
|
||||
|
||||
@ -36,14 +36,15 @@ namespace rdf {
|
||||
bool trace() const { return Trace; }
|
||||
DataFlowGraph &getDFG() { return DFG; }
|
||||
|
||||
typedef std::map<RegisterRef, RegisterRef> EqualityMap;
|
||||
using EqualityMap = std::map<RegisterRef, RegisterRef>;
|
||||
|
||||
virtual bool interpretAsCopy(const MachineInstr *MI, EqualityMap &EM);
|
||||
|
||||
private:
|
||||
const MachineDominatorTree &MDT;
|
||||
DataFlowGraph &DFG;
|
||||
Liveness L;
|
||||
bool Trace;
|
||||
bool Trace = false;
|
||||
|
||||
// map: statement -> (map: dst reg -> src reg)
|
||||
std::map<NodeId, EqualityMap> CopyMap;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFGraph.cpp -----------------------------------------------------===//
|
||||
//===- RDFGraph.cpp -------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -10,6 +10,8 @@
|
||||
// Target-independent, SSA-based data flow graph for register data flow (RDF).
|
||||
//
|
||||
#include "RDFGraph.h"
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
@ -23,16 +25,19 @@
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -201,7 +206,7 @@ namespace {
|
||||
struct PrintListV {
|
||||
PrintListV(const NodeList &L, const DataFlowGraph &G) : List(L), G(G) {}
|
||||
|
||||
typedef T Type;
|
||||
using Type = T;
|
||||
const NodeList &List;
|
||||
const DataFlowGraph &G;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFGraph.h ---------------------------------------------*- C++ -*-===//
|
||||
//===- RDFGraph.h -----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -226,17 +226,13 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
|
||||
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
@ -250,17 +246,19 @@ static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineOperand;
|
||||
class MachineDominanceFrontier;
|
||||
class MachineDominatorTree;
|
||||
class TargetInstrInfo;
|
||||
class MachineBasicBlock;
|
||||
class MachineDominanceFrontier;
|
||||
class MachineDominatorTree;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineOperand;
|
||||
class raw_ostream;
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
typedef uint32_t NodeId;
|
||||
using NodeId = uint32_t;
|
||||
|
||||
struct DataFlowGraph;
|
||||
|
||||
@ -335,7 +333,7 @@ namespace rdf {
|
||||
};
|
||||
|
||||
template <typename T> struct NodeAddr {
|
||||
NodeAddr() : Addr(nullptr) {}
|
||||
NodeAddr() = default;
|
||||
NodeAddr(T A, NodeId I) : Addr(A), Id(I) {}
|
||||
|
||||
// Type cast (casting constructor). The reason for having this class
|
||||
@ -351,7 +349,7 @@ namespace rdf {
|
||||
return !operator==(NA);
|
||||
}
|
||||
|
||||
T Addr;
|
||||
T Addr = nullptr;
|
||||
NodeId Id = 0;
|
||||
};
|
||||
|
||||
@ -408,11 +406,11 @@ namespace rdf {
|
||||
const uint32_t IndexMask;
|
||||
char *ActiveEnd = nullptr;
|
||||
std::vector<char*> Blocks;
|
||||
typedef BumpPtrAllocatorImpl<MallocAllocator, 65536> AllocatorTy;
|
||||
using AllocatorTy = BumpPtrAllocatorImpl<MallocAllocator, 65536>;
|
||||
AllocatorTy MemPool;
|
||||
};
|
||||
|
||||
typedef std::set<RegisterRef> RegisterSet;
|
||||
using RegisterSet = std::set<RegisterRef>;
|
||||
|
||||
struct TargetOperandInfo {
|
||||
TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
|
||||
@ -437,10 +435,12 @@ namespace rdf {
|
||||
LaneBitmask getLaneMaskForIndex(uint32_t K) const {
|
||||
return K == 0 ? LaneBitmask::getAll() : get(K);
|
||||
}
|
||||
|
||||
uint32_t getIndexForLaneMask(LaneBitmask LM) {
|
||||
assert(LM.any());
|
||||
return LM.all() ? 0 : insert(LM);
|
||||
}
|
||||
|
||||
uint32_t getIndexForLaneMask(LaneBitmask LM) const {
|
||||
assert(LM.any());
|
||||
return LM.all() ? 0 : find(LM);
|
||||
@ -463,8 +463,10 @@ namespace rdf {
|
||||
|
||||
// Insert node NA after "this" in the circular chain.
|
||||
void append(NodeAddr<NodeBase*> NA);
|
||||
|
||||
// Initialize all members to 0.
|
||||
void init() { memset(this, 0, sizeof *this); }
|
||||
|
||||
void setNext(NodeId N) { Next = N; }
|
||||
|
||||
protected:
|
||||
@ -508,9 +510,8 @@ namespace rdf {
|
||||
static_assert(sizeof(NodeBase) <= NodeAllocator::NodeMemSize,
|
||||
"NodeBase must be at most NodeAllocator::NodeMemSize bytes");
|
||||
|
||||
// typedef std::vector<NodeAddr<NodeBase*>> NodeList;
|
||||
typedef SmallVector<NodeAddr<NodeBase*>,4> NodeList;
|
||||
typedef std::set<NodeId> NodeSet;
|
||||
using NodeList = SmallVector<NodeAddr<NodeBase *>, 4>;
|
||||
using NodeSet = std::set<NodeId>;
|
||||
|
||||
struct RefNode : public NodeBase {
|
||||
RefNode() = default;
|
||||
@ -672,9 +673,9 @@ namespace rdf {
|
||||
bool empty() const { return Stack.empty() || top() == bottom(); }
|
||||
|
||||
private:
|
||||
typedef NodeAddr<DefNode*> value_type;
|
||||
using value_type = NodeAddr<DefNode *>;
|
||||
struct Iterator {
|
||||
typedef DefStack::value_type value_type;
|
||||
using value_type = DefStack::value_type;
|
||||
|
||||
Iterator &up() { Pos = DS.nextUp(Pos); return *this; }
|
||||
Iterator &down() { Pos = DS.nextDown(Pos); return *this; }
|
||||
@ -691,17 +692,19 @@ namespace rdf {
|
||||
bool operator!=(const Iterator &It) const { return Pos != It.Pos; }
|
||||
|
||||
private:
|
||||
friend struct DefStack;
|
||||
|
||||
Iterator(const DefStack &S, bool Top);
|
||||
|
||||
// Pos-1 is the index in the StorageType object that corresponds to
|
||||
// the top of the DefStack.
|
||||
const DefStack &DS;
|
||||
unsigned Pos;
|
||||
friend struct DefStack;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Iterator iterator;
|
||||
using iterator = Iterator;
|
||||
|
||||
iterator top() const { return Iterator(*this, true); }
|
||||
iterator bottom() const { return Iterator(*this, false); }
|
||||
unsigned size() const;
|
||||
@ -713,7 +716,8 @@ namespace rdf {
|
||||
|
||||
private:
|
||||
friend struct Iterator;
|
||||
typedef std::vector<value_type> StorageType;
|
||||
|
||||
using StorageType = std::vector<value_type>;
|
||||
|
||||
bool isDelimiter(const StorageType::value_type &P, NodeId N = 0) const {
|
||||
return (P.Addr == nullptr) && (N == 0 || P.Id == N);
|
||||
@ -727,7 +731,7 @@ namespace rdf {
|
||||
|
||||
// Make this std::unordered_map for speed of accessing elements.
|
||||
// Map: Register (physical or virtual) -> DefStack
|
||||
typedef std::unordered_map<RegisterId,DefStack> DefStackMap;
|
||||
using DefStackMap = std::unordered_map<RegisterId, DefStack>;
|
||||
|
||||
void build(unsigned Options = BuildOptions::None);
|
||||
void pushAllDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
|
||||
@ -839,7 +843,7 @@ namespace rdf {
|
||||
locateNextRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
|
||||
Predicate P) const;
|
||||
|
||||
typedef std::map<NodeId,RegisterSet> BlockRefsMap;
|
||||
using BlockRefsMap = std::map<NodeId, RegisterSet>;
|
||||
|
||||
void buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In);
|
||||
void buildBlockRefs(NodeAddr<BlockNode*> BA, BlockRefsMap &RefM);
|
||||
@ -923,7 +927,6 @@ namespace rdf {
|
||||
return MM;
|
||||
}
|
||||
|
||||
|
||||
template <typename T> struct Print;
|
||||
template <typename T>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<T> &P);
|
||||
@ -931,6 +934,7 @@ namespace rdf {
|
||||
template <typename T>
|
||||
struct Print {
|
||||
Print(const T &x, const DataFlowGraph &g) : Obj(x), G(g) {}
|
||||
|
||||
const T &Obj;
|
||||
const DataFlowGraph &G;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFLiveness.cpp --------------------------------------------------===//
|
||||
//===- RDFLiveness.cpp ----------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -25,14 +25,29 @@
|
||||
//
|
||||
#include "RDFLiveness.h"
|
||||
#include "RDFGraph.h"
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineDominanceFrontier.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace rdf;
|
||||
@ -42,6 +57,7 @@ static cl::opt<unsigned> MaxRecNest("rdf-liveness-max-rec", cl::init(25),
|
||||
|
||||
namespace llvm {
|
||||
namespace rdf {
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<Liveness::RefMap> &P) {
|
||||
OS << '{';
|
||||
@ -57,8 +73,9 @@ namespace rdf {
|
||||
OS << " }";
|
||||
return OS;
|
||||
}
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
|
||||
} // end namespace rdf
|
||||
} // end namespace llvm
|
||||
|
||||
// The order in the returned sequence is the order of reaching defs in the
|
||||
// upward traversal: the first def is the closest to the given reference RefA,
|
||||
@ -245,19 +262,17 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
|
||||
auto DeadP = [](const NodeAddr<DefNode*> DA) -> bool {
|
||||
return DA.Addr->getFlags() & NodeAttrs::Dead;
|
||||
};
|
||||
RDefs.resize(std::distance(RDefs.begin(), remove_if(RDefs, DeadP)));
|
||||
RDefs.resize(std::distance(RDefs.begin(), llvm::remove_if(RDefs, DeadP)));
|
||||
|
||||
return RDefs;
|
||||
}
|
||||
|
||||
|
||||
std::pair<NodeSet,bool>
|
||||
Liveness::getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
|
||||
NodeSet &Visited, const NodeSet &Defs) {
|
||||
return getAllReachingDefsRecImpl(RefRR, RefA, Visited, Defs, 0, MaxRecNest);
|
||||
}
|
||||
|
||||
|
||||
std::pair<NodeSet,bool>
|
||||
Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
|
||||
NodeSet &Visited, const NodeSet &Defs, unsigned Nest, unsigned MaxNest) {
|
||||
@ -363,7 +378,6 @@ NodeAddr<RefNode*> Liveness::getNearestAliasedRef(RegisterRef RefRR,
|
||||
return NodeAddr<RefNode*>();
|
||||
}
|
||||
|
||||
|
||||
NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
|
||||
NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs) {
|
||||
NodeSet Uses;
|
||||
@ -410,7 +424,6 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
|
||||
return Uses;
|
||||
}
|
||||
|
||||
|
||||
void Liveness::computePhiInfo() {
|
||||
RealUseMap.clear();
|
||||
|
||||
@ -668,7 +681,6 @@ void Liveness::computePhiInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Liveness::computeLiveIns() {
|
||||
// Populate the node-to-block map. This speeds up the calculations
|
||||
// significantly.
|
||||
@ -822,7 +834,6 @@ void Liveness::computeLiveIns() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Liveness::resetLiveIns() {
|
||||
for (auto &B : DFG.getMF()) {
|
||||
// Remove all live-ins.
|
||||
@ -840,13 +851,11 @@ void Liveness::resetLiveIns() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Liveness::resetKills() {
|
||||
for (auto &B : DFG.getMF())
|
||||
resetKills(&B);
|
||||
}
|
||||
|
||||
|
||||
void Liveness::resetKills(MachineBasicBlock *B) {
|
||||
auto CopyLiveIns = [this] (MachineBasicBlock *B, BitVector &LV) -> void {
|
||||
for (auto I : B->liveins()) {
|
||||
@ -909,7 +918,6 @@ void Liveness::resetKills(MachineBasicBlock *B) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Helper function to obtain the basic block containing the reaching def
|
||||
// of the given use.
|
||||
MachineBasicBlock *Liveness::getBlockWithRef(NodeId RN) const {
|
||||
@ -919,7 +927,6 @@ MachineBasicBlock *Liveness::getBlockWithRef(NodeId RN) const {
|
||||
llvm_unreachable("Node id not in map");
|
||||
}
|
||||
|
||||
|
||||
void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
// The LiveIn map, for each (physical) register, contains the set of live
|
||||
// reaching defs of that register that are live on entry to the associated
|
||||
@ -1107,9 +1114,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Liveness::emptify(RefMap &M) {
|
||||
for (auto I = M.begin(), E = M.end(); I != E; )
|
||||
I = I->second.empty() ? M.erase(I) : std::next(I);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFLiveness.h ----------------------------------------------------===//
|
||||
//===- RDFLiveness.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -10,24 +10,27 @@
|
||||
// Recalculate the liveness information given a data flow graph.
|
||||
// This includes block live-ins and kill flags.
|
||||
|
||||
#ifndef RDF_LIVENESS_H
|
||||
#define RDF_LIVENESS_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H
|
||||
|
||||
#include "RDFGraph.h"
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include <map>
|
||||
|
||||
using namespace llvm;
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineRegisterInfo;
|
||||
class TargetRegisterInfo;
|
||||
class MachineDominatorTree;
|
||||
class MachineDominanceFrontier;
|
||||
|
||||
class MachineBasicBlock;
|
||||
class MachineDominanceFrontier;
|
||||
class MachineDominatorTree;
|
||||
class MachineRegisterInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
struct Liveness {
|
||||
public:
|
||||
// This is really a std::map, except that it provides a non-trivial
|
||||
@ -38,32 +41,36 @@ namespace rdf {
|
||||
RegisterAggr &operator[] (MachineBasicBlock *B) {
|
||||
return Map.emplace(B, Empty).first->second;
|
||||
}
|
||||
|
||||
private:
|
||||
RegisterAggr Empty;
|
||||
std::map<MachineBasicBlock*,RegisterAggr> Map;
|
||||
};
|
||||
|
||||
typedef std::pair<NodeId,LaneBitmask> NodeRef;
|
||||
typedef std::set<NodeRef> NodeRefSet;
|
||||
using NodeRef = std::pair<NodeId, LaneBitmask>;
|
||||
using NodeRefSet = std::set<NodeRef>;
|
||||
// RegisterId in RefMap must be normalized.
|
||||
typedef std::map<RegisterId,NodeRefSet> RefMap;
|
||||
using RefMap = std::map<RegisterId, NodeRefSet>;
|
||||
|
||||
Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
|
||||
: DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
|
||||
MDF(g.getDF()), LiveMap(g.getPRI()), Empty(),
|
||||
NoRegs(g.getPRI()), Trace(false) {}
|
||||
MDF(g.getDF()), LiveMap(g.getPRI()), NoRegs(g.getPRI()) {}
|
||||
|
||||
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
|
||||
bool TopShadows, bool FullChain, const RegisterAggr &DefRRs);
|
||||
|
||||
NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
|
||||
return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false,
|
||||
false, NoRegs);
|
||||
}
|
||||
|
||||
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
|
||||
return getAllReachingDefs(RefRR, RefA, false, false, NoRegs);
|
||||
}
|
||||
|
||||
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
|
||||
const RegisterAggr &DefRRs);
|
||||
|
||||
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
|
||||
return getAllReachedUses(RefRR, DefA, NoRegs);
|
||||
}
|
||||
@ -76,6 +83,7 @@ namespace rdf {
|
||||
|
||||
LiveMapType &getLiveMap() { return LiveMap; }
|
||||
const LiveMapType &getLiveMap() const { return LiveMap; }
|
||||
|
||||
const RefMap &getRealUses(NodeId P) const {
|
||||
auto F = RealUseMap.find(P);
|
||||
return F == RealUseMap.end() ? Empty : F->second;
|
||||
@ -98,12 +106,12 @@ namespace rdf {
|
||||
LiveMapType LiveMap;
|
||||
const RefMap Empty;
|
||||
const RegisterAggr NoRegs;
|
||||
bool Trace;
|
||||
bool Trace = false;
|
||||
|
||||
// Cache of mapping from node ids (for RefNodes) to the containing
|
||||
// basic blocks. Not computing it each time for each node reduces
|
||||
// the liveness calculation time by a large fraction.
|
||||
typedef DenseMap<NodeId,MachineBasicBlock*> NodeBlockMap;
|
||||
using NodeBlockMap = DenseMap<NodeId, MachineBasicBlock *>;
|
||||
NodeBlockMap NBMap;
|
||||
|
||||
// Phi information:
|
||||
@ -134,7 +142,9 @@ namespace rdf {
|
||||
NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs,
|
||||
unsigned Nest, unsigned MaxNest);
|
||||
};
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
|
||||
#endif // RDF_LIVENESS_H
|
||||
} // end namespace rdf
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_RDFLIVENESS_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFRegisters.cpp ---------------------------------------*- C++ -*-===//
|
||||
//===- RDFRegisters.cpp ---------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -10,6 +10,17 @@
|
||||
#include "RDFRegisters.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace rdf;
|
||||
@ -227,7 +238,6 @@ RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
|
||||
llvm_unreachable("Invalid arguments: unrelated registers?");
|
||||
}
|
||||
|
||||
|
||||
bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
|
||||
if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
|
||||
return Units.anyCommon(PRI.getMaskUnits(RR.Reg));
|
||||
@ -369,4 +379,3 @@ RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG,
|
||||
Pos = End ? Masks.end() : Masks.begin();
|
||||
Index = End ? Masks.size() : 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFRegisters.h -----------------------------------------*- C++ -*-===//
|
||||
//===- RDFRegisters.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,16 +11,23 @@
|
||||
#define LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineFunction;
|
||||
class raw_ostream;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
typedef uint32_t RegisterId;
|
||||
using RegisterId = uint32_t;
|
||||
|
||||
// Template class for a map translating uint32_t into arbitrary types.
|
||||
// The map will act like an indexed set: upon insertion of a new object,
|
||||
@ -28,7 +35,7 @@ namespace rdf {
|
||||
// as invalid and is never allocated.
|
||||
template <typename T, unsigned N = 32>
|
||||
struct IndexedSet {
|
||||
IndexedSet() : Map() { Map.reserve(N); }
|
||||
IndexedSet() { Map.reserve(N); }
|
||||
|
||||
T get(uint32_t Idx) const {
|
||||
// Index Idx corresponds to Map[Idx-1].
|
||||
@ -53,7 +60,8 @@ namespace rdf {
|
||||
|
||||
uint32_t size() const { return Map.size(); }
|
||||
|
||||
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||
using const_iterator = typename std::vector<T>::const_iterator;
|
||||
|
||||
const_iterator begin() const { return Map.begin(); }
|
||||
const_iterator end() const { return Map.end(); }
|
||||
|
||||
@ -72,12 +80,15 @@ namespace rdf {
|
||||
operator bool() const {
|
||||
return Reg != 0 && Mask.any();
|
||||
}
|
||||
|
||||
bool operator== (const RegisterRef &RR) const {
|
||||
return Reg == RR.Reg && Mask == RR.Mask;
|
||||
}
|
||||
|
||||
bool operator!= (const RegisterRef &RR) const {
|
||||
return !operator==(RR);
|
||||
}
|
||||
|
||||
bool operator< (const RegisterRef &RR) const {
|
||||
return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
|
||||
}
|
||||
@ -91,12 +102,15 @@ namespace rdf {
|
||||
static bool isRegMaskId(RegisterId R) {
|
||||
return TargetRegisterInfo::isStackSlot(R);
|
||||
}
|
||||
|
||||
RegisterId getRegMaskId(const uint32_t *RM) const {
|
||||
return TargetRegisterInfo::index2StackSlot(RegMasks.find(RM));
|
||||
}
|
||||
|
||||
const uint32_t *getRegMaskBits(RegisterId R) const {
|
||||
return RegMasks.get(TargetRegisterInfo::stackSlot2Index(R));
|
||||
}
|
||||
|
||||
RegisterRef normalize(RegisterRef RR) const;
|
||||
|
||||
bool alias(RegisterRef RA, RegisterRef RB) const {
|
||||
@ -104,16 +118,18 @@ namespace rdf {
|
||||
return !isRegMaskId(RB.Reg) ? aliasRR(RA, RB) : aliasRM(RA, RB);
|
||||
return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
|
||||
}
|
||||
|
||||
std::set<RegisterId> getAliasSet(RegisterId Reg) const;
|
||||
|
||||
RegisterRef getRefForUnit(uint32_t U) const {
|
||||
return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
|
||||
}
|
||||
|
||||
const BitVector &getMaskUnits(RegisterId MaskId) const {
|
||||
return MaskInfos[TargetRegisterInfo::stackSlot2Index(MaskId)].Units;
|
||||
}
|
||||
RegisterRef mapTo(RegisterRef RR, unsigned R) const;
|
||||
|
||||
RegisterRef mapTo(RegisterRef RR, unsigned R) const;
|
||||
const TargetRegisterInfo &getTRI() const { return TRI; }
|
||||
|
||||
private:
|
||||
@ -139,7 +155,6 @@ namespace rdf {
|
||||
bool aliasMM(RegisterRef RM, RegisterRef RN) const;
|
||||
};
|
||||
|
||||
|
||||
struct RegisterAggr {
|
||||
RegisterAggr(const PhysicalRegisterInfo &pri)
|
||||
: Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
|
||||
@ -148,6 +163,7 @@ namespace rdf {
|
||||
bool empty() const { return Units.none(); }
|
||||
bool hasAliasOf(RegisterRef RR) const;
|
||||
bool hasCoverOf(RegisterRef RR) const;
|
||||
|
||||
static bool isCoverOf(RegisterRef RA, RegisterRef RB,
|
||||
const PhysicalRegisterInfo &PRI) {
|
||||
return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
|
||||
@ -167,26 +183,32 @@ namespace rdf {
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
struct rr_iterator {
|
||||
typedef std::map<RegisterId,LaneBitmask> MapType;
|
||||
using MapType = std::map<RegisterId, LaneBitmask>;
|
||||
|
||||
private:
|
||||
MapType Masks;
|
||||
MapType::iterator Pos;
|
||||
unsigned Index;
|
||||
const RegisterAggr *Owner;
|
||||
|
||||
public:
|
||||
rr_iterator(const RegisterAggr &RG, bool End);
|
||||
|
||||
RegisterRef operator*() const {
|
||||
return RegisterRef(Pos->first, Pos->second);
|
||||
}
|
||||
|
||||
rr_iterator &operator++() {
|
||||
++Pos;
|
||||
++Index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const rr_iterator &I) const {
|
||||
assert(Owner == I.Owner);
|
||||
return Index == I.Index;
|
||||
}
|
||||
|
||||
bool operator!=(const rr_iterator &I) const {
|
||||
return !(*this == I);
|
||||
}
|
||||
@ -204,7 +226,6 @@ namespace rdf {
|
||||
const PhysicalRegisterInfo &PRI;
|
||||
};
|
||||
|
||||
|
||||
// Optionally print the lane mask, if it is not ~0.
|
||||
struct PrintLaneMaskOpt {
|
||||
PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
|
||||
@ -212,8 +233,8 @@ namespace rdf {
|
||||
};
|
||||
raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
|
||||
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
} // end namespace rdf
|
||||
|
||||
#endif
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user