mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 20:29:48 +00:00
e83e5d460d
Spilling can insert instructions almost anywhere, and this can mess up control flow lowering in a multitude of ways, due to instruction reordering. Let's sort this out the easy way: never spill registers involved with control flow, i.e. saved EXEC masks. Unfortunately, this does not work at all with optimizations disabled, as the register allocator ignores spill weights. This should be addressed in a future commit. The test was reduced from the "stacks" shader of [1]. Some issues trigger the machine verifier while another one is checked manually. [1] http://madebyevan.com/webgl-path-tracing/ v2: only insert pass with optimizations enabled, merge test runs. Patch by: Grigori Goronzy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237152 91177308-0d34-0410-b5e6-96231b3b80d8
97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
//===-- SIFixControlFlowLiveIntervals.cpp - Fix CF live intervals ---------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file
|
|
/// \brief Spilling of EXEC masks used for control flow messes up control flow
|
|
/// lowering, so mark all live intervals associated with CF instructions as
|
|
/// non-spillable.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "AMDGPU.h"
|
|
#include "SIInstrInfo.h"
|
|
#include "SIRegisterInfo.h"
|
|
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/MachinePostDominators.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "si-fix-cf-live-intervals"
|
|
|
|
namespace {
|
|
|
|
class SIFixControlFlowLiveIntervals : public MachineFunctionPass {
|
|
public:
|
|
static char ID;
|
|
|
|
public:
|
|
SIFixControlFlowLiveIntervals() : MachineFunctionPass(ID) {
|
|
initializeSIFixControlFlowLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
const char *getPassName() const override {
|
|
return "SI Fix CF Live Intervals";
|
|
}
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.addRequired<LiveIntervals>();
|
|
AU.setPreservesAll();
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
}
|
|
};
|
|
|
|
} // End anonymous namespace.
|
|
|
|
INITIALIZE_PASS_BEGIN(SIFixControlFlowLiveIntervals, DEBUG_TYPE,
|
|
"SI Fix CF Live Intervals", false, false)
|
|
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
|
INITIALIZE_PASS_END(SIFixControlFlowLiveIntervals, DEBUG_TYPE,
|
|
"SI Fix CF Live Intervals", false, false)
|
|
|
|
char SIFixControlFlowLiveIntervals::ID = 0;
|
|
|
|
char &llvm::SIFixControlFlowLiveIntervalsID = SIFixControlFlowLiveIntervals::ID;
|
|
|
|
FunctionPass *llvm::createSIFixControlFlowLiveIntervalsPass() {
|
|
return new SIFixControlFlowLiveIntervals();
|
|
}
|
|
|
|
bool SIFixControlFlowLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
|
|
LiveIntervals *LIS = &getAnalysis<LiveIntervals>();
|
|
|
|
for (const MachineBasicBlock &MBB : MF) {
|
|
for (const MachineInstr &MI : MBB) {
|
|
switch (MI.getOpcode()) {
|
|
case AMDGPU::SI_IF:
|
|
case AMDGPU::SI_ELSE:
|
|
case AMDGPU::SI_BREAK:
|
|
case AMDGPU::SI_IF_BREAK:
|
|
case AMDGPU::SI_ELSE_BREAK:
|
|
case AMDGPU::SI_END_CF: {
|
|
unsigned Reg = MI.getOperand(0).getReg();
|
|
LIS->getInterval(Reg).markNotSpillable();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|