Skip to content

Commit

Permalink
backend:修复了栈上基址浮动的存在的bug
Browse files Browse the repository at this point in the history
  • Loading branch information
youngk1019 committed Jul 12, 2023
1 parent 221429e commit 6634d80
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 99 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@
- `clang_O2`: 使用 clang -O2 编译并运行测试样例
- `ssyc_llvm`: 使用我们的编译器编译出 llvm ir, 并使用 llvm-as/llc 转为汇编文件, 随后汇编并运行测试样例
- `ssyc_asm`: 使用我们的编译器编译出汇编文件, 随后汇编并运行测试样例
- `ssyc_asm_O2`: 使用我们的编译器编译出汇编文件, 并执行所有的优化, 随后汇编并运行测试样例
- `ssyc_llvm_long`: 使用我们的编译器编译出 llvm ir, 并使用 llvm-as/llc 转为汇编文件, 随后汇编并运行测试样例, 在出现用例结果错误时不会停止
- `ssyc_asm_long`: 使用我们的编译器编译出汇编文件, 随后汇编并运行测试样例, 在出现用例结果错误时不会停止
- `ssyc_asm_O2_long`: 使用我们的编译器编译出汇编文件, 并执行所有的优化, 随后汇编并运行测试样例, 在出现用例结果错误时不会停止
- `generate_stdout`: 使用 clang -O2 编译并运行用例, 保存运行结果, 相当于构造标准答案

## 程序本体参数说明
Expand All @@ -90,7 +92,7 @@
当前程序的测试主要以目测编译后程序的返回值为主. 一个输出的例子为:

```
$ ./m test inst-combine ssyc_asm
$ ./m test inst-combine ssyc_asm_O2_long
[12:03:08] Finish: ANTLR Generation
[12:03:12] Finish: Java compile
================= begin: ssyc =================
Expand Down
6 changes: 4 additions & 2 deletions local-test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ def check_funcs(funcs):
'clang': [clang, gcc_as, run],
'clang_O2': [clang_O2, gcc_as, run],

'generate_stdout': [clang_O2, gcc_as, generate_stdout]
'generate_stdout': [clang_O2, gcc_as, generate_stdout],
'retest': [llc, gcc_as, run_for_long_time, print_fail]
}

try:
Expand All @@ -326,7 +327,8 @@ def check_funcs(funcs):
funcs = test_items[test_item]
# check_funcs(funcs)

clear_up()
if test_item != 'retest':
clear_up()
for func in funcs:
func(subdir)

Expand Down
2 changes: 1 addition & 1 deletion m
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ make_jar() {
}

run() {
java -cp "lib/*:target" Main $@
java -cp "lib/*:target" Main $@ -O2
}

run_jar() {
Expand Down
4 changes: 2 additions & 2 deletions src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public static void main(String[] args) {
var needLog = false;
var flagCnt = 0;
for (var arg : args) {
if (arg.equalsIgnoreCase("-o2")) {
if (arg.equalsIgnoreCase("-o2") || arg.equalsIgnoreCase("-o1")) {
needOptimize = true;
flagCnt++;
}
if (arg.equalsIgnoreCase("--log")) {
if (arg.equalsIgnoreCase("-log")) {
needLog = true;
flagCnt++;
}
Expand Down
25 changes: 14 additions & 11 deletions src/backend/lir/ArmBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import utils.INode;
import utils.INodeOwner;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;

public class ArmBlock implements IListOwner<ArmInst, ArmBlock>, INodeOwner<ArmBlock, ArmFunction> {
public static class BlockLiveInfo {
Expand Down Expand Up @@ -66,21 +63,26 @@ public void setLiveOut(Set<Reg> liveOut) {

private final BlockLiveInfo blockLiveInfo;

private final Set<Addr> haveRecoverAddrs;
private final Set<Addr> haveRecoverAddr;

private final Set<IImm> haveRecoverOffset;
private final Map<IImm, Integer> haveRecoverFixedOffset;
private final Map<IImm, Integer> haveRecoverOffset;

private final Set<IImm> haveRecoverLoadParam;

private final Set<IImm> haveRecoverStackLoad;

private final Set<Imm> haveRecoverImm;

public Set<Addr> getHaveRecoverAddrs() {
return haveRecoverAddrs;
public Set<Addr> getHaveRecoverAddr() {
return haveRecoverAddr;
}

public Set<IImm> getHaveRecoverOffset() {
public Map<IImm, Integer> getHaveRecoverFixedOffset() {
return haveRecoverFixedOffset;
}

public Map<IImm, Integer> getHaveRecoverOffset() {
return haveRecoverOffset;
}

Expand Down Expand Up @@ -159,8 +161,9 @@ public ArmBlock(String label) {
this.label = label;
this.pred = new ArrayList<>();
this.blockLiveInfo = new BlockLiveInfo();
this.haveRecoverAddrs = new HashSet<>();
this.haveRecoverOffset = new HashSet<>();
this.haveRecoverAddr = new HashSet<>();
this.haveRecoverFixedOffset = new HashMap<>();
this.haveRecoverOffset = new HashMap<>();
this.haveRecoverLoadParam = new HashSet<>();
this.haveRecoverStackLoad = new HashSet<>();
this.haveRecoverImm = new HashSet<>();
Expand Down
14 changes: 11 additions & 3 deletions src/backend/lir/inst/ArmInstStackAddr.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,17 @@ public ArmInstStackAddr(Operand dst, IImm offset) {
this.isFix = false;
}

public Operand getDst() { return getOperand(0); }
public Operand getSrc() { return getOperand(1); }
public IImm getOffset() { return (IImm) getOperand(2); }
public Operand getDst() {
return getOperand(0);
}

public Operand getSrc() {
return getOperand(1);
}

public IImm getOffset() {
return (IImm) getOperand(2);
}

public int getIntOffset() {
return Objects.requireNonNullElse(trueOffset, getOffset()).getImm();
Expand Down
4 changes: 4 additions & 0 deletions src/backend/lir/operand/Reg.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public static Set<Reg> getAllAllocatableRegs() {
return result;
}

public static int getAllocatableRegsCnt(boolean isInteger) {
return isInteger ? IPhyReg.getIntAllocatableRegs().size() : FPhyReg.getFloatAllocatableRegs().size();
}

protected Reg(OperandKind s) {
super(s);
}
Expand Down
124 changes: 107 additions & 17 deletions src/backend/regallocator/RegAllocManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import backend.lir.inst.*;
import backend.lir.operand.*;
import utils.Log;
import utils.Pair;

import java.util.*;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -90,9 +91,12 @@ private boolean fixStack(ArmFunction func) {
}
Map<Integer, Operand> stackAddrMap = new HashMap<>();
Map<Operand, Integer> addrStackMap = new HashMap<>();
Map<Integer, Operand> fixedStackAddrMap = new HashMap<>();
Map<Operand, Integer> fixedAddrStackMap = new HashMap<>();
Log.ensure(stackSize == func.getFinalStackSize(), "stack size error");

int finalStackSize = stackSize;
// System.out.println("stacksize:" + stackSize);
// 修复ArmInstAddr的寻址
BiFunction<ArmInstAddr, Integer, Boolean> fixArmInstAddr = (inst, trueOffset) -> {
boolean isInstFix = false;
Expand All @@ -102,7 +106,8 @@ private boolean fixStack(ArmFunction func) {
for (var entry : stackAddrMap.entrySet()) {
var offset = entry.getKey();
var op = entry.getValue();
if (offset <= trueOffset && ImmUtils.checkOffsetRange(trueOffset - offset, inst.getDst())) {
// 因为stackaddr 其基准的为4 然后调整了为1024 但这个时候4092的偏移量选择了这个基准之后 会变成>=4096 但stackaddr的TrueOffset不会调整
if (offset - 1020 <= trueOffset && ImmUtils.checkOffsetRange(trueOffset - (offset - 1020), inst.getDst())) {
inst.replaceAddr(op);
inst.setTrueOffset(new IImm(trueOffset - offset));
func.getSpillNodes().remove(op);
Expand All @@ -128,7 +133,7 @@ private boolean fixStack(ArmFunction func) {
} else {
var addrTrueOffset = addrStackMap.get(inst.getAddr());
var nowTrueOffset = trueOffset - addrTrueOffset;
Log.ensure(ImmUtils.checkOffsetRange(nowTrueOffset, inst.getDst()), "check offset is illegal");
Log.ensure(ImmUtils.checkOffsetRange(nowTrueOffset, inst.getDst()), "check offset is illegal" + nowTrueOffset + "," + addrTrueOffset + "," + trueOffset);
inst.setTrueOffset(new IImm(nowTrueOffset));
}
} else {
Expand All @@ -145,18 +150,61 @@ private boolean fixStack(ArmFunction func) {
Log.ensure(stackMap.containsKey(stackAddr.getOffset().getImm()), "stack offset not present");
stackAddr.setTrueOffset(new IImm(stackMap.get(stackAddr.getOffset().getImm())));
} else if (stackAddr.isFix()) {
continue;
fixedStackAddrMap.put(stackAddr.getOffset().getImm(), stackAddr.getDst());
fixedAddrStackMap.put(stackAddr.getDst(), stackAddr.getOffset().getImm());
} else {
int oldTrueOffset = stackSize - stackAddr.getOffset().getImm();
int nowTrueOffset = (oldTrueOffset + 1023) / 1024 * 1024;
stackAddr.replaceOffset(new IImm(stackSize - nowTrueOffset));
// System.out.println("old:" + stackAddr.getTrueOffset().getImm() + " new:" + nowTrueOffset);
// stackAddr.replaceOffset(new IImm(stackSize - nowTrueOffset));
// 不应该修改基准值
stackAddr.setTrueOffset(new IImm(nowTrueOffset));
stackAddrMap.put(nowTrueOffset, stackAddr.getDst());
addrStackMap.put(stackAddr.getDst(), nowTrueOffset);
}
} else if (inst instanceof ArmInstParamLoad paramLoad) {
int trueOffset = paramLoad.getOffset().getImm() + stackSize + 4 * regCnt;
isFix |= fixArmInstAddr.apply(paramLoad, trueOffset);
if (!ImmUtils.checkOffsetRange(trueOffset, paramLoad.getDst())) {
if (!paramLoad.getAddr().equals(IPhyReg.SP)) {
var addrTrueOffset = fixedAddrStackMap.get(paramLoad.getAddr());
var nowTrueOffset = trueOffset - addrTrueOffset;
if (!ImmUtils.checkOffsetRange(nowTrueOffset, paramLoad.getDst())) {
paramLoad.replaceAddr(IPhyReg.SP);
}
paramLoad.setTrueOffset(new IImm(nowTrueOffset));
}
if (paramLoad.getAddr().equals(IPhyReg.SP)) {
isFix = true;
for (var entry : fixedStackAddrMap.entrySet()) {
var offset = entry.getKey();
var op = entry.getValue();
if (offset <= trueOffset && ImmUtils.checkOffsetRange(trueOffset - offset, paramLoad.getDst())) {
paramLoad.replaceAddr(op);
paramLoad.setTrueOffset(new IImm(trueOffset - offset));
func.getSpillNodes().remove(op);
// 相当于当前节点改变了生命周期
break;
}
}
if (paramLoad.getAddr().equals(IPhyReg.SP)) {
int addrTrueOffset = trueOffset / 1024 * 1024;
var vr = new IVirtualReg();
var stackAddr = new ArmInstStackAddr(vr, new IImm(addrTrueOffset));
stackAddr.setFix(true);
paramLoad.insertBeforeCO(stackAddr);
paramLoad.replaceAddr(vr);
Log.ensure(trueOffset >= addrTrueOffset, "chang offset is illegal");
Log.ensure(ImmUtils.checkOffsetRange(trueOffset - addrTrueOffset, paramLoad.getDst()),
"chang offset is illegal");
paramLoad.setTrueOffset(new IImm(trueOffset - addrTrueOffset));
fixedStackAddrMap.put(addrTrueOffset, vr);
fixedAddrStackMap.put(vr, addrTrueOffset);
func.getStackAddrMap().put(vr, stackAddr);
}
}
} else {
paramLoad.setTrueOffset(new IImm(trueOffset));
}
} else if (inst instanceof ArmInstStackLoad stackLoad) {
Log.ensure(stackMap.containsKey(stackLoad.getOffset().getImm()), "stack offset not present");
int trueOffset = stackMap.get(stackLoad.getOffset().getImm());
Expand All @@ -176,30 +224,71 @@ private boolean recoverRegAllocate(ArmFunction func) {
Map<Operand, Operand> recoverMap = new HashMap<>();
for (var block : func) {
Map<Addr, Operand> addrMap = new HashMap<>();
Map<IImm, Operand> offsetMap = new HashMap<>();
Map<IImm, Pair<Operand, Integer>> fixedOffsetMap = new HashMap<>();
Map<IImm, Pair<Operand, Integer>> offsetMap = new HashMap<>();
Map<IImm, Operand> paramMap = new HashMap<>();
Map<IImm, Operand> stackLoadMap = new HashMap<>();
Map<Imm, Operand> immMap = new HashMap<>();
var haveRecoverAddrs = block.getHaveRecoverAddrs();
var haveRecoverAddr = block.getHaveRecoverAddr();
var haveRecoverFixedOffset = block.getHaveRecoverFixedOffset();
var haveRecoverOffset = block.getHaveRecoverOffset();
var haveRecoverLoadParam = block.getHaveRecoverLoadParam();
var haveRecoverImm = block.getHaveRecoverImm();
var haveRecoverStackLoad = block.getHaveRecoverStackLoad();
Map<Operand, Integer> opUsedMap = new HashMap<>();
for (var inst : block) {
for (var reg : inst.getRegUse()) {
opUsedMap.put(reg, opUsedMap.getOrDefault(reg, 0) + 1);
}
}
int p = 0;
for (var inst : block) {
boolean jump = false;
for (var def : inst.getRegDef()) {
if (opUsedMap.getOrDefault(def, 0) >= 4) {
jump = true;
break;
}
}
if (jump) {
continue;
}
if (inst instanceof ArmInstStackAddr stackAddr) {
// 恢复一个基本块内的基准地址
var offset = stackAddr.getOffset();
if (!stackAddr.getDst().isVirtual()) {
continue;
}
if (offsetMap.containsKey(offset)) {
recoverMap.put(stackAddr.getDst(), offsetMap.get(offset));
stackAddr.freeFromIList();
isFix = true;
} else if (!haveRecoverOffset.contains(offset)) {
haveRecoverOffset.add(offset);
offsetMap.put(offset, stackAddr.getDst());
func.getSpillNodes().remove(stackAddr.getDst());
if (stackAddr.isFix()) {
if (fixedOffsetMap.containsKey(offset)) {
if (p - haveRecoverFixedOffset.getOrDefault(offset, 64) < fixedOffsetMap.get(offset).getValue()) {
recoverMap.put(stackAddr.getDst(), fixedOffsetMap.get(offset).getKey());
stackAddr.freeFromIList();
} else {
fixedOffsetMap.put(offset, new Pair<>(stackAddr.getDst(), p));
func.getSpillNodes().remove(stackAddr.getDst());
}
isFix = true;
} else if (haveRecoverFixedOffset.getOrDefault(offset, 64) >= 64) {
haveRecoverFixedOffset.put(offset, haveRecoverFixedOffset.getOrDefault(offset, 64) / 2);
fixedOffsetMap.put(offset, new Pair<>(stackAddr.getDst(), p));
func.getSpillNodes().remove(stackAddr.getDst());
}
} else {
if (offsetMap.containsKey(offset)) {
if (p - haveRecoverOffset.getOrDefault(offset, 64) < offsetMap.get(offset).getValue()) {
recoverMap.put(stackAddr.getDst(), offsetMap.get(offset).getKey());
stackAddr.freeFromIList();
} else {
offsetMap.put(offset, new Pair<>(stackAddr.getDst(), p));
func.getSpillNodes().remove(stackAddr.getDst());
}
isFix = true;
} else if (haveRecoverOffset.getOrDefault(offset, 64) >= 64) {
haveRecoverOffset.put(offset, haveRecoverFixedOffset.getOrDefault(offset, 64) / 2);
offsetMap.put(offset, new Pair<>(stackAddr.getDst(), p));
func.getSpillNodes().remove(stackAddr.getDst());
}
}
}
if (inst instanceof ArmInstLoad load) {
Expand All @@ -214,8 +303,8 @@ private boolean recoverRegAllocate(ArmFunction func) {
recoverMap.put(load.getDst(), addrMap.get(addr));
load.freeFromIList();
isFix = true;
} else if (!haveRecoverAddrs.contains(addr)) {
haveRecoverAddrs.add(addr);
} else if (!haveRecoverAddr.contains(addr)) {
haveRecoverAddr.add(addr);
addrMap.put(addr, load.getDst());
func.getSpillNodes().remove(load.getDst());
}
Expand Down Expand Up @@ -294,6 +383,7 @@ private boolean recoverRegAllocate(ArmFunction func) {
func.getStackLoadMap().put(store.getDst(), new ArmInstStackLoad(store.getDst(), offset));
}
}
p++;
}
}
for (var block : func) {
Expand Down
Loading

0 comments on commit 6634d80

Please sign in to comment.