Skip to content

Commit 3cc01e9

Browse files
committed
[EVM] Do stackification of instructions in the EVMStackify pass to have valid MIR
This change moves the place where normal instructions are replaced with their 'stack' counterparts from the EVMMCInstLower to the EVMStackify pass. This ensures we have a valid MIR after each pass. This change also contains some updates in how labels are represented and resolved in the BE.
1 parent 876ffb6 commit 3cc01e9

20 files changed

+271
-122
lines changed

llvm/lib/Target/EVM/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ add_llvm_target(EVMCodeGen
3636
EVMStackify.cpp
3737
EVMSubtarget.cpp
3838
EVMTargetMachine.cpp
39-
EVMTargetObjectFile.cpp
4039
EVMTargetTransformInfo.cpp
4140

4241
LINK_COMPONENTS

llvm/lib/Target/EVM/EVMAsmPrinter.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,36 @@ class EVMAsmPrinter : public AsmPrinter {
3939

4040
StringRef getPassName() const override { return "EVM Assembly "; }
4141

42+
void SetupMachineFunction(MachineFunction &MF) override;
43+
4244
void emitInstruction(const MachineInstr *MI) override;
4345

4446
void emitFunctionEntryLabel() override;
47+
48+
/// Return true if the basic block has exactly one predecessor and the control
49+
/// transfer mechanism between the predecessor and this block is a
50+
/// fall-through.
51+
bool isBlockOnlyReachableByFallthrough(
52+
const MachineBasicBlock *MBB) const override;
4553
};
4654
} // end of anonymous namespace
4755

56+
void EVMAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
57+
// Unbundle <push_label, jump> bundles.
58+
for (MachineBasicBlock &MBB : MF) {
59+
MachineBasicBlock::instr_iterator I = MBB.instr_begin(),
60+
E = MBB.instr_end();
61+
for (; I != E; ++I) {
62+
if (I->isBundledWithPred()) {
63+
assert(I->isConditionalBranch() || I->isUnconditionalBranch());
64+
I->unbundleFromPred();
65+
}
66+
}
67+
}
68+
69+
AsmPrinter::SetupMachineFunction(MF);
70+
}
71+
4872
void EVMAsmPrinter::emitFunctionEntryLabel() {
4973
AsmPrinter::emitFunctionEntryLabel();
5074

@@ -70,12 +94,17 @@ void EVMAsmPrinter::emitFunctionEntryLabel() {
7094
void EVMAsmPrinter::emitInstruction(const MachineInstr *MI) {
7195
EVMMCInstLower MCInstLowering(OutContext, *this, VRegMapping,
7296
MF->getRegInfo());
73-
7497
MCInst TmpInst;
7598
MCInstLowering.Lower(MI, TmpInst);
7699
EmitToStreamer(*OutStreamer, TmpInst);
77100
}
78101

102+
bool EVMAsmPrinter::isBlockOnlyReachableByFallthrough(
103+
const MachineBasicBlock *MBB) const {
104+
// For simplicity, always emit BB labels.
105+
return false;
106+
}
107+
79108
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMAsmPrinter() {
80109
const RegisterAsmPrinter<EVMAsmPrinter> X(getTheEVMTarget());
81110
}

llvm/lib/Target/EVM/EVMISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ SDValue EVMTargetLowering::LowerFormalArguments(
387387
fail(DL, DAG, "VarArg is not supported yet");
388388

389389
MachineFunction &MF = DAG.getMachineFunction();
390-
auto *MFI = MF.getInfo<EVMFunctionInfo>();
390+
auto *MFI = MF.getInfo<EVMMachineFunctionInfo>();
391391

392392
// Set up the incoming ARGUMENTS value, which serves to represent the liveness
393393
// of the incoming values before they're represented by virtual registers.

llvm/lib/Target/EVM/EVMInstrInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "EVMInstrInfo.h"
14+
#include "EVMMachineFunctionInfo.h"
1415
#include "MCTargetDesc/EVMMCTargetDesc.h"
1516
using namespace llvm;
1617

@@ -65,6 +66,12 @@ bool EVMInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
6566
FBB = nullptr;
6667
Cond.clear();
6768

69+
const auto *MFI = MBB.getParent()->getInfo<EVMMachineFunctionInfo>();
70+
if (MFI->getIsStackified()) {
71+
LLVM_DEBUG(dbgs() << "Can't analyze terminators in stackified code");
72+
return true;
73+
}
74+
6875
// Iterate backwards and analyze all terminators.
6976
MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend();
7077
while (I != E) {

llvm/lib/Target/EVM/EVMInstrInfo.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ foreach I = {1-16} in {
794794

795795
defm PUSH0 : I<(outs), (ins), [], "PUSH0", "", 0x5F, 2>;
796796

797-
def PUSH8_LABEL : NI<(outs), (ins jmptarget:$dst), [], false, "", 0, 0> {
797+
def PUSH_LABEL : NI<(outs), (ins jmptarget:$dst), [], false, "", 0, 0> {
798798
let isCodeGenOnly = 1;
799799
}
800800

@@ -1122,7 +1122,7 @@ def PUSH32_S : NI<(outs), (ins i256imm:$imm), [], true, "PUSH32 $imm",
11221122
}
11231123

11241124
// Pseudo instructions for linkage
1125-
let isCodeGenOnly = 1 in
1126-
defm DATA
1127-
: I<(outs GPR:$dst), (ins jmptarget:$reloc), [], "",
1128-
"", 0, 0>;
1125+
let isCodeGenOnly = 1, BaseName = "DATA" in {
1126+
def DATA : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>;
1127+
def DATA_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0>;
1128+
}

llvm/lib/Target/EVM/EVMMCInstLower.cpp

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,33 +27,23 @@ using namespace llvm;
2727

2828
extern cl::opt<bool> EVMKeepRegisters;
2929

30-
static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI) {
31-
// Remove all uses of stackified registers to bring the instruction format
32-
// into its final stack form used throughout MC, and transition opcodes to
33-
// their _S variant.
30+
// Stackify instruction that were not stackified before.
31+
// Only two instructions need to be stackified here: PUSH_LABEL and DATA_S,
32+
static void stackifyInstruction(const MachineInstr *MI, MCInst &OutMI) {
3433
if (MI->isDebugInstr() || MI->isLabel() || MI->isInlineAsm())
3534
return;
3635

37-
// Transform 'register' instruction to 'stack' one.
38-
unsigned RegOpcode = OutMI.getOpcode();
39-
if (RegOpcode == EVM::PUSH8_LABEL) {
40-
// Replace PUSH8_LABEL with PUSH8_S opcode.
41-
OutMI.setOpcode(EVM::PUSH8_S);
42-
} else {
43-
unsigned StackOpcode = EVM::getStackOpcode(RegOpcode);
44-
OutMI.setOpcode(StackOpcode);
45-
}
36+
// Check there are no register operands.
37+
assert(std::all_of(OutMI.begin(), OutMI.end(),
38+
[](const MCOperand &MO) { return !MO.isReg(); }));
4639

47-
// Remove register operands.
48-
for (auto I = OutMI.getNumOperands(); I; --I) {
49-
auto &MO = OutMI.getOperand(I - 1);
50-
if (MO.isReg()) {
51-
OutMI.erase(&MO);
52-
}
53-
}
54-
55-
if (RegOpcode == EVM::DATA)
40+
// Set up final opcodes for the following codegen-only instructions.
41+
unsigned Opcode = OutMI.getOpcode();
42+
if (Opcode == EVM::PUSH_LABEL || Opcode == EVM::DATA_S)
5643
OutMI.setOpcode(EVM::PUSH4_S);
44+
45+
// Check that all the instructions are in the 'stack' form.
46+
assert(EVM::getRegisterOpcode(OutMI.getOpcode()));
5747
}
5848

5949
MCSymbol *
@@ -136,7 +126,7 @@ void EVMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) {
136126
case MachineOperand::MO_MCSymbol: {
137127
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VariantKind::VK_None;
138128
unsigned Opc = MI->getOpcode();
139-
if (Opc == EVM::DATA)
129+
if (Opc == EVM::DATA_S)
140130
Kind = MCSymbolRefExpr::VariantKind::VK_EVM_DATA;
141131

142132
MCOp = MCOperand::createExpr(
@@ -156,7 +146,7 @@ void EVMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) {
156146
OutMI.addOperand(MCOp);
157147
}
158148
if (!EVMKeepRegisters)
159-
removeRegisterOperands(MI, OutMI);
149+
stackifyInstruction(MI, OutMI);
160150
else if (Desc.variadicOpsAreDefs())
161151
OutMI.insert(OutMI.begin(), MCOperand::createImm(MI->getNumExplicitDefs()));
162152
}

llvm/lib/Target/EVM/EVMMachineFunctionInfo.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,26 @@
1313
#include "EVMMachineFunctionInfo.h"
1414
using namespace llvm;
1515

16-
EVMFunctionInfo::~EVMFunctionInfo() = default; // anchor.
16+
EVMMachineFunctionInfo::~EVMMachineFunctionInfo() = default;
1717

18-
MachineFunctionInfo *
19-
EVMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
20-
const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
21-
&Src2DstMBB) const {
22-
return DestMF.cloneInfo<EVMFunctionInfo>(*this);
18+
MachineFunctionInfo *EVMMachineFunctionInfo::clone(
19+
BumpPtrAllocator &Allocator, MachineFunction &DestMF,
20+
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
21+
const {
22+
return DestMF.cloneInfo<EVMMachineFunctionInfo>(*this);
23+
}
24+
25+
yaml::EVMMachineFunctionInfo::~EVMMachineFunctionInfo() = default;
26+
27+
yaml::EVMMachineFunctionInfo::EVMMachineFunctionInfo(
28+
const llvm::EVMMachineFunctionInfo &MFI)
29+
: IsStackified(MFI.getIsStackified()) {}
30+
31+
void yaml::EVMMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
32+
MappingTraits<EVMMachineFunctionInfo>::mapping(YamlIO, *this);
33+
}
34+
35+
void EVMMachineFunctionInfo::initializeBaseYamlFields(
36+
const yaml::EVMMachineFunctionInfo &YamlMFI) {
37+
IsStackified = YamlMFI.IsStackified;
2338
}

llvm/lib/Target/EVM/EVMMachineFunctionInfo.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,33 @@
1616
#include "MCTargetDesc/EVMMCTargetDesc.h"
1717
#include "llvm/CodeGen/MIRYamlMapping.h"
1818
#include "llvm/CodeGen/MachineRegisterInfo.h"
19-
#include "llvm/MC/MCSymbolWasm.h"
2019

2120
namespace llvm {
2221

22+
class EVMMachineFunctionInfo;
23+
24+
namespace yaml {
25+
26+
struct EVMMachineFunctionInfo final : public yaml::MachineFunctionInfo {
27+
bool IsStackified = false;
28+
29+
EVMMachineFunctionInfo() = default;
30+
explicit EVMMachineFunctionInfo(const llvm::EVMMachineFunctionInfo &MFI);
31+
~EVMMachineFunctionInfo() override;
32+
33+
void mappingImpl(yaml::IO &YamlIO) override;
34+
};
35+
36+
template <> struct MappingTraits<EVMMachineFunctionInfo> {
37+
static void mapping(IO &YamlIO, EVMMachineFunctionInfo &MFI) {
38+
YamlIO.mapOptional("isStackified", MFI.IsStackified, false);
39+
}
40+
};
41+
} // end namespace yaml
42+
2343
/// This class is derived from MachineFunctionInfo and contains private
2444
/// EVM-specific information for each MachineFunction.
25-
class EVMFunctionInfo final : public MachineFunctionInfo {
45+
class EVMMachineFunctionInfo final : public MachineFunctionInfo {
2646
/// A mapping from CodeGen vreg index to a boolean value indicating whether
2747
/// the given register is considered to be "stackified", meaning it has been
2848
/// determined or made to meet the stack requirements:
@@ -34,16 +54,21 @@ class EVMFunctionInfo final : public MachineFunctionInfo {
3454
/// Number of parameters. Their type doesn't matter as it always is i256.
3555
unsigned NumberOfParameters = 0;
3656

57+
/// If the MF's instructions are in 'stack' form.
58+
bool IsStackified = false;
59+
3760
public:
38-
explicit EVMFunctionInfo(MachineFunction &MF) {}
39-
EVMFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {}
40-
~EVMFunctionInfo() override;
61+
explicit EVMMachineFunctionInfo(MachineFunction &MF) {}
62+
EVMMachineFunctionInfo(const Function &F, const TargetSubtargetInfo *STI) {}
63+
~EVMMachineFunctionInfo() override;
4164

4265
MachineFunctionInfo *
4366
clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
4467
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
4568
const override;
4669

70+
void initializeBaseYamlFields(const yaml::EVMMachineFunctionInfo &YamlMFI);
71+
4772
void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg) {
4873
assert(MRI.getUniqueVRegDef(VReg));
4974
auto I = Register::virtReg2Index(VReg);
@@ -72,7 +97,12 @@ class EVMFunctionInfo final : public MachineFunctionInfo {
7297
unsigned getNumParams() const {
7398
return NumberOfParameters;
7499
}
100+
101+
void setIsStackified(bool Val = true) { IsStackified = Val; }
102+
103+
bool getIsStackified() const { return IsStackified; }
75104
};
105+
76106
} // end namespace llvm
77107

78108
#endif // LLVM_LIB_TARGET_EVM_EVMMACHINEFUNCTIONINFO_H

llvm/lib/Target/EVM/EVMRegColoring.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ bool EVMRegColoring::runOnMachineFunction(MachineFunction &MF) {
8080
LiveIntervals *Liveness = &getAnalysis<LiveIntervals>();
8181
const MachineBlockFrequencyInfo *MBFI =
8282
&getAnalysis<MachineBlockFrequencyInfo>();
83-
EVMFunctionInfo &MFI = *MF.getInfo<EVMFunctionInfo>();
83+
EVMMachineFunctionInfo &MFI = *MF.getInfo<EVMMachineFunctionInfo>();
8484

8585
// Gather all register intervals into a list and sort them.
8686
unsigned NumVRegs = MRI->getNumVirtRegs();

llvm/lib/Target/EVM/EVMSingleUseExpression.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ static bool shouldRematerialize(const MachineInstr &Def,
268268
// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
269269
// more precise.
270270
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use,
271-
const MachineInstr *Insert, const EVMFunctionInfo &MFI,
271+
const MachineInstr *Insert,
272+
const EVMMachineFunctionInfo &MFI,
272273
const MachineRegisterInfo &MRI) {
273274
const MachineInstr *DefI = Def->getParent();
274275
const MachineInstr *UseI = Use->getParent();
@@ -390,7 +391,7 @@ static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
390391
static MachineInstr *moveForSingleUse(unsigned Reg, MachineOperand &Op,
391392
MachineInstr *Def, MachineBasicBlock &MBB,
392393
MachineInstr *Insert, LiveIntervals &LIS,
393-
EVMFunctionInfo &MFI,
394+
EVMMachineFunctionInfo &MFI,
394395
MachineRegisterInfo &MRI) {
395396
LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
396397

@@ -430,8 +431,8 @@ static MachineInstr *moveForSingleUse(unsigned Reg, MachineOperand &Op,
430431
static MachineInstr *rematerializeCheapDef(
431432
unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB,
432433
MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS,
433-
EVMFunctionInfo &MFI, MachineRegisterInfo &MRI, const EVMInstrInfo *TII,
434-
const EVMRegisterInfo *TRI) {
434+
EVMMachineFunctionInfo &MFI, MachineRegisterInfo &MRI,
435+
const EVMInstrInfo *TII, const EVMRegisterInfo *TRI) {
435436
LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
436437
LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
437438

@@ -593,7 +594,7 @@ bool EVMSingleUseExpression::runOnMachineFunction(MachineFunction &MF) {
593594

594595
bool Changed = false;
595596
MachineRegisterInfo &MRI = MF.getRegInfo();
596-
EVMFunctionInfo &MFI = *MF.getInfo<EVMFunctionInfo>();
597+
EVMMachineFunctionInfo &MFI = *MF.getInfo<EVMMachineFunctionInfo>();
597598
const auto *TII = MF.getSubtarget<EVMSubtarget>().getInstrInfo();
598599
const auto *TRI = MF.getSubtarget<EVMSubtarget>().getRegisterInfo();
599600
auto &MDT = getAnalysis<MachineDominatorTree>();

0 commit comments

Comments
 (0)