mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
Sooooo many of these had incorrect or strange main module includes. I have manually inspected all of these, and fixed the main module include to be the nearest plausible thing I could find. If you own or care about any of these source files, I encourage you to take some time and check that these edits were sensible. I can't have broken anything (I strictly added headers, and reordered them, never removed), but they may not be the headers you'd really like to identify as containing the API being implemented. Many forward declarations and missing includes were added to a header files to allow them to parse cleanly when included first. The main module rule does in fact have its merits. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169131 91177308-0d34-0410-b5e6-96231b3b80d8
217 lines
7.8 KiB
C++
217 lines
7.8 KiB
C++
//===-- HexagonSplitTFRCondSets.cpp - split TFR condsets into xfers -------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// This pass tries to provide opportunities for better optimization of muxes.
|
|
// The default code generated for something like: flag = (a == b) ? 1 : 3;
|
|
// would be:
|
|
//
|
|
// {p0 = cmp.eq(r0,r1)}
|
|
// {r3 = mux(p0,#1,#3)}
|
|
//
|
|
// This requires two packets. If we use .new predicated immediate transfers,
|
|
// then we can do this in a single packet, e.g.:
|
|
//
|
|
// {p0 = cmp.eq(r0,r1)
|
|
// if (p0.new) r3 = #1
|
|
// if (!p0.new) r3 = #3}
|
|
//
|
|
// Note that the conditional assignments are not generated in .new form here.
|
|
// We assume opptimisically that they will be formed later.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "xfer"
|
|
#include "Hexagon.h"
|
|
#include "HexagonMachineFunctionInfo.h"
|
|
#include "HexagonSubtarget.h"
|
|
#include "HexagonTargetMachine.h"
|
|
#include "llvm/CodeGen/LatencyPriorityQueue.h"
|
|
#include "llvm/CodeGen/MachineDominators.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/CodeGen/Passes.h"
|
|
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
|
#include "llvm/CodeGen/SchedulerRegistry.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/MathExtras.h"
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
class HexagonSplitTFRCondSets : public MachineFunctionPass {
|
|
HexagonTargetMachine& QTM;
|
|
const HexagonSubtarget &QST;
|
|
|
|
public:
|
|
static char ID;
|
|
HexagonSplitTFRCondSets(HexagonTargetMachine& TM) :
|
|
MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {}
|
|
|
|
const char *getPassName() const {
|
|
return "Hexagon Split TFRCondSets";
|
|
}
|
|
bool runOnMachineFunction(MachineFunction &Fn);
|
|
};
|
|
|
|
|
|
char HexagonSplitTFRCondSets::ID = 0;
|
|
|
|
|
|
bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
|
|
|
|
const TargetInstrInfo *TII = QTM.getInstrInfo();
|
|
|
|
// Loop over all of the basic blocks.
|
|
for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
|
|
MBBb != MBBe; ++MBBb) {
|
|
MachineBasicBlock* MBB = MBBb;
|
|
// Traverse the basic block.
|
|
for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
|
|
++MII) {
|
|
MachineInstr *MI = MII;
|
|
int Opc1, Opc2;
|
|
switch(MI->getOpcode()) {
|
|
case Hexagon::TFR_condset_rr:
|
|
case Hexagon::TFR_condset_rr_f:
|
|
case Hexagon::TFR_condset_rr64_f: {
|
|
int DestReg = MI->getOperand(0).getReg();
|
|
int SrcReg1 = MI->getOperand(2).getReg();
|
|
int SrcReg2 = MI->getOperand(3).getReg();
|
|
|
|
if (MI->getOpcode() == Hexagon::TFR_condset_rr ||
|
|
MI->getOpcode() == Hexagon::TFR_condset_rr_f) {
|
|
Opc1 = Hexagon::TFR_cPt;
|
|
Opc2 = Hexagon::TFR_cNotPt;
|
|
}
|
|
else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) {
|
|
Opc1 = Hexagon::TFR64_cPt;
|
|
Opc2 = Hexagon::TFR64_cNotPt;
|
|
}
|
|
|
|
// Minor optimization: do not emit the predicated copy if the source
|
|
// and the destination is the same register.
|
|
if (DestReg != SrcReg1) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc1),
|
|
DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
|
|
}
|
|
if (DestReg != SrcReg2) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc2),
|
|
DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
|
|
}
|
|
MII = MBB->erase(MI);
|
|
--MII;
|
|
break;
|
|
}
|
|
case Hexagon::TFR_condset_ri:
|
|
case Hexagon::TFR_condset_ri_f: {
|
|
int DestReg = MI->getOperand(0).getReg();
|
|
int SrcReg1 = MI->getOperand(2).getReg();
|
|
|
|
// Do not emit the predicated copy if the source and the destination
|
|
// is the same register.
|
|
if (DestReg != SrcReg1) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFR_cPt), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
|
|
}
|
|
if (MI->getOpcode() == Hexagon::TFR_condset_ri ) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cNotPt), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).
|
|
addImm(MI->getOperand(3).getImm());
|
|
} else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cNotPt_f), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).
|
|
addFPImm(MI->getOperand(3).getFPImm());
|
|
}
|
|
|
|
MII = MBB->erase(MI);
|
|
--MII;
|
|
break;
|
|
}
|
|
case Hexagon::TFR_condset_ir:
|
|
case Hexagon::TFR_condset_ir_f: {
|
|
int DestReg = MI->getOperand(0).getReg();
|
|
int SrcReg2 = MI->getOperand(3).getReg();
|
|
|
|
if (MI->getOpcode() == Hexagon::TFR_condset_ir ) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cPt), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).
|
|
addImm(MI->getOperand(2).getImm());
|
|
} else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cPt_f), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).
|
|
addFPImm(MI->getOperand(2).getFPImm());
|
|
}
|
|
|
|
// Do not emit the predicated copy if the source and
|
|
// the destination is the same register.
|
|
if (DestReg != SrcReg2) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFR_cNotPt), DestReg).
|
|
addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
|
|
}
|
|
MII = MBB->erase(MI);
|
|
--MII;
|
|
break;
|
|
}
|
|
case Hexagon::TFR_condset_ii:
|
|
case Hexagon::TFR_condset_ii_f: {
|
|
int DestReg = MI->getOperand(0).getReg();
|
|
int SrcReg1 = MI->getOperand(1).getReg();
|
|
|
|
if (MI->getOpcode() == Hexagon::TFR_condset_ii ) {
|
|
int Immed1 = MI->getOperand(2).getImm();
|
|
int Immed2 = MI->getOperand(3).getImm();
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cPt),
|
|
DestReg).addReg(SrcReg1).addImm(Immed1);
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cNotPt),
|
|
DestReg).addReg(SrcReg1).addImm(Immed2);
|
|
} else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) {
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cPt_f), DestReg).
|
|
addReg(SrcReg1).
|
|
addFPImm(MI->getOperand(2).getFPImm());
|
|
BuildMI(*MBB, MII, MI->getDebugLoc(),
|
|
TII->get(Hexagon::TFRI_cNotPt_f), DestReg).
|
|
addReg(SrcReg1).
|
|
addFPImm(MI->getOperand(3).getFPImm());
|
|
}
|
|
MII = MBB->erase(MI);
|
|
--MII;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Public Constructor Functions
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
FunctionPass *llvm::createHexagonSplitTFRCondSets(HexagonTargetMachine &TM) {
|
|
return new HexagonSplitTFRCondSets(TM);
|
|
}
|