Skip to content

Commit

Permalink
[EVM] Handle unused function parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
PavelKopyl committed Oct 26, 2024
1 parent be3b27f commit ab5456f
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 9 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/EVM/EVMControlFlowGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ struct CFG {
struct FunctionInfo {
MachineFunction *MF = nullptr;
BasicBlock *Entry = nullptr;
std::vector<VariableSlot> Parameters;
std::vector<StackSlot> Parameters;
std::vector<BasicBlock *> Exits;
bool CanContinue = true;
};
Expand Down
18 changes: 16 additions & 2 deletions llvm/lib/Target/EVM/EVMControlFlowGraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "EVMControlFlowGraphBuilder.h"
#include "EVMHelperUtilities.h"
#include "EVMMachineFunctionInfo.h"
#include "EVMStackDebug.h"
#include "EVMSubtarget.h"
#include "MCTargetDesc/EVMMCTargetDesc.h"
Expand Down Expand Up @@ -123,6 +124,18 @@ std::unique_ptr<CFG> ControlFlowGraphBuilder::build(MachineFunction &MF,
if (F.hasFnAttribute(Attribute::NoReturn))
Result->FuncInfo.CanContinue = false;

// Handle function parameters
auto *MFI = MF.getInfo<EVMMachineFunctionInfo>();
Result->FuncInfo.Parameters =
std::vector<StackSlot>(MFI->getNumParams(), JunkSlot{});
for (const MachineInstr &MI : MF.front()) {
if (MI.getOpcode() == EVM::ARGUMENT) {
int64_t ArgIdx = MI.getOperand(1).getImm();
Result->FuncInfo.Parameters[ArgIdx] =
VariableSlot{MI.getOperand(0).getReg()};
}
}

for (MachineBasicBlock &MBB : MF)
Builder.handleBasicBlock(MBB);

Expand Down Expand Up @@ -201,8 +214,7 @@ void ControlFlowGraphBuilder::handleMachineInstr(MachineInstr &MI) {
llvm_unreachable("Unexpected stack memory instruction");
return;
case EVM::ARGUMENT:
Cfg.FuncInfo.Parameters.emplace_back(
VariableSlot{MI.getOperand(0).getReg()});
// Is handled above.
return;
case EVM::FCALL:
handleFunctionCall(MI);
Expand Down Expand Up @@ -314,6 +326,8 @@ void ControlFlowGraphBuilder::handleReturn(const MachineInstr &MI) {
collectInstrOperands(MI, Input, Output);
// We need to reverse input operands to restore original ordering,
// as it is in the instruction.
// Calling convention: return values are passed in stack such that the
// last one specified in the RET instruction is passed on the stack TOP.
std::reverse(Input.begin(), Input.end());
CurrentBlock->Exit =
CFG::BasicBlock::FunctionReturn{std::move(Input), &Cfg.FuncInfo};
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/EVM/EVMOptimizedCodeTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,8 @@ void EVMOptimizedCodeTransform::operator()() {
if (FuncInfo->CanContinue)
CurrentStack.emplace_back(FunctionReturnLabelSlot{FuncInfo->MF});

// Calling convention: input arguments are passed in stack such that the
// first one specified in the function declaration is passed on the stack TOP.
for (auto const &Param : reverse(FuncInfo->Parameters))
CurrentStack.emplace_back(Param);

Expand Down
10 changes: 8 additions & 2 deletions llvm/lib/Target/EVM/EVMStackDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,14 @@ void StackLayoutPrinter::operator()(CFG::BasicBlock const &Block,

void StackLayoutPrinter::operator()(CFG::FunctionInfo const &Info) {
OS << "Function: " << Info.MF->getName() << "(";
for (const auto &Param : Info.Parameters)
OS << printReg(Param.VirtualReg, nullptr, 0, nullptr);
for (const StackSlot &ParamSlot : Info.Parameters) {
if (const auto *Slot = std::get_if<VariableSlot>(&ParamSlot))
OS << printReg(Slot->VirtualReg, nullptr, 0, nullptr) << ' ';
else if (const auto *Slot = std::get_if<JunkSlot>(&ParamSlot))
OS << "[unused param] ";
else
llvm_unreachable("Unexpected stack slot");
}
OS << ");\n";
OS << "FunctionEntry " << " -> Block" << getBlockId(*Info.Entry) << ";\n";
(*this)(*Info.Entry, false);
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/Target/EVM/EVMTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,13 @@ void EVMPassConfig::addPreEmitPass() {
addPass(&MachineBlockPlacementID);
addPass(createEVMOptimizeLiveIntervals());
addPass(createEVMSingleUseExpression());
// Run the register coloring pass to reduce the total number of registers.
addPass(createEVMRegColoring());
if (EVMUseLocalStakify)
if (EVMUseLocalStakify) {
// Run the register coloring pass to reduce the total number of registers.
addPass(createEVMRegColoring());
addPass(createEVMStackify());
else
} else {
addPass(createEVMStackifyEF());
}
}
}

Expand Down
52 changes: 52 additions & 0 deletions llvm/test/CodeGen/EVM/unused_function_arguments.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
; RUN: llc < %s | FileCheck %s

target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256"
target triple = "evm"

define i256 @foo(i256 %a1, i256 %a2, i256 %a3) nounwind {
; CHECK-LABEL: @foo
; CHECK: JUMPDEST
; CHECK-NEXT: SWAP2
; CHECK-NEXT: POP
; CHECK-NEXT: POP
; CHECK-NEXT: DUP1
; CHECK-NEXT: ADD
; CHECK-NEXT: SWAP1
; CHECK-NEXT: JUMP

%x1 = add i256 %a1, %a1
ret i256 %x1
}

define i256 @wat(i256 %a1, i256 %a2, i256 %a3) nounwind {
; CHECK-LABEL: @wat
; CHECK: JUMPDEST
; CHECK-NEXT: POP
; CHECK-NEXT: SWAP1
; CHECK-NEXT: POP
; CHECK-NEXT: DUP1
; CHECK-NEXT: ADD
; CHECK-NEXT: SWAP1
; CHECK-NEXT: JUMP

%x1 = add i256 %a2, %a2
ret i256 %x1
}

define i256 @bar() nounwind {
; CHECK-LABEL: @bar
; CHECK: JUMPDEST
; CHECK-NEXT: PUSH4 @.FUNC_RET0
; CHECK-NEXT: PUSH1 3
; CHECK-NEXT: PUSH1 2
; CHECK-NEXT: PUSH1 1
; CHECK-NEXT: PUSH4 @foo
; CHECK-NEXT: JUMP
; CHECK-LABEL: .FUNC_RET0:
; CHECK-NEXT: JUMPDEST
; CHECK-NEXT: SWAP1
; CHECK-NEXT: JUMP

%res = call i256 @foo(i256 1, i256 2, i256 3)
ret i256 %res
}

0 comments on commit ab5456f

Please sign in to comment.