|
@@ -39,6 +39,7 @@ unit aoptx86;
|
|
|
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
|
|
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
|
|
function RegReadByInstruction(reg : TRegister; hp : tai) : boolean;
|
|
|
+ function GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
|
|
|
protected
|
|
|
{ checks whether loading a new value in reg1 overwrites the entirety of reg2 }
|
|
|
function Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
|
|
@@ -274,6 +275,19 @@ unit aoptx86;
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ function TX86AsmOptimizer.GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
|
|
|
+ begin
|
|
|
+ Next:=Current;
|
|
|
+ repeat
|
|
|
+ Result:=GetNextInstruction(Next,Next);
|
|
|
+ until not (Result) or
|
|
|
+ not(cs_opt_level3 in current_settings.optimizerswitches) or
|
|
|
+ (Next.typ<>ait_instruction) or
|
|
|
+ RegInInstruction(reg,Next) or
|
|
|
+ is_calljmp(taicpu(Next).opcode);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
function TX86AsmOptimizer.InstructionLoadsFromReg(const reg: TRegister;const hp: tai): boolean;
|
|
|
begin
|
|
|
Result:=RegReadByInstruction(reg,hp);
|
|
@@ -2181,6 +2195,34 @@ unit aoptx86;
|
|
|
result:=true;
|
|
|
end;
|
|
|
end;
|
|
|
+ { changes
|
|
|
+ lea offset1(regX), reg1
|
|
|
+ lea offset2(reg1), reg1
|
|
|
+ to
|
|
|
+ lea offset1+offset2(regX), reg1 }
|
|
|
+ if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[1]^.reg) and
|
|
|
+ MatchInstruction(hp1,A_LEA,[S_L]) and
|
|
|
+ MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^) and
|
|
|
+ (taicpu(hp1).oper[0]^.ref^.base=taicpu(p).oper[1]^.reg) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.index=NR_NO) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.relsymbol=nil) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.segment=NR_NO) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.symbol=nil) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.index=taicpu(hp1).oper[0]^.ref^.index) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.relsymbol=taicpu(hp1).oper[0]^.ref^.relsymbol) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.scalefactor=taicpu(hp1).oper[0]^.ref^.scalefactor) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.segment=taicpu(hp1).oper[0]^.ref^.segment) and
|
|
|
+ (taicpu(p).oper[0]^.ref^.symbol=taicpu(hp1).oper[0]^.ref^.symbol) then
|
|
|
+ begin
|
|
|
+ DebugMsg(SPeepholeOptimization + 'LeaLea2Lea done',p);
|
|
|
+ inc(taicpu(hp1).oper[0]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
|
|
|
+ taicpu(hp1).oper[0]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
|
|
|
+ asml.Remove(p);
|
|
|
+ p.Free;
|
|
|
+ p:=hp1;
|
|
|
+ result:=true;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
|