Skip to content

Commit 073ad2c

Browse files
committed
Add triple pattern optimization
This implements 3-instruction sequence optimizations: - Store-load-store elimination: removes unused intermediate loads - Consecutive stores: only last store to same location matters
1 parent 2cce7c3 commit 073ad2c

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/peephole.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,87 @@ bool bitwise_optimization(ph2_ir_t *ph2_ir)
855855
return false;
856856
}
857857

858+
/* Triple pattern optimization: Handle 3-instruction sequences
859+
* These patterns are more complex but offer significant optimization
860+
* opportunities Returns true if optimization was applied
861+
*/
862+
bool triple_pattern_optimization(ph2_ir_t *ph2_ir)
863+
{
864+
if (!ph2_ir || !ph2_ir->next || !ph2_ir->next->next)
865+
return false;
866+
867+
ph2_ir_t *second = ph2_ir->next;
868+
ph2_ir_t *third = second->next;
869+
870+
/* Pattern 1: Store-load-store elimination
871+
* {store val1, addr; load r, addr; store val2, addr}
872+
* The middle load is pointless if not used elsewhere
873+
*/
874+
if (ph2_ir->op == OP_store && second->op == OP_load &&
875+
third->op == OP_store &&
876+
ph2_ir->src1 == second->src0 && /* same address */
877+
ph2_ir->dest == second->src1 && /* same offset */
878+
second->src0 == third->src1 && /* same address */
879+
second->src1 == third->dest) { /* same offset */
880+
/* Check if the loaded value is used by the third store */
881+
if (third->src0 != second->dest) {
882+
/* The load result is not used, can eliminate it */
883+
ph2_ir->next = third;
884+
return true;
885+
}
886+
}
887+
888+
/* Pattern 2: Consecutive stores to same location
889+
* {store v1, addr; store v2, addr; store v3, addr}
890+
* Only the last store matters
891+
*/
892+
if (ph2_ir->op == OP_store && second->op == OP_store &&
893+
third->op == OP_store && ph2_ir->src1 == second->src1 &&
894+
ph2_ir->dest == second->dest && second->src1 == third->src1 &&
895+
second->dest == third->dest) {
896+
/* All three stores go to the same location */
897+
/* Only the last one matters, eliminate first two */
898+
ph2_ir->src0 = third->src0; /* Use last value */
899+
ph2_ir->next = third->next; /* Skip middle stores */
900+
return true;
901+
}
902+
903+
/* FIXME: Additional patterns for future implementation:
904+
*
905+
* Pattern 3: Load-op-store with same location
906+
* {load r1, [addr]; op r2, r1, ...; store r2, [addr]}
907+
* Can optimize to in-place operation if possible
908+
* Requires architecture-specific support in codegen.
909+
*
910+
* Pattern 4: Redundant comparison after boolean operation
911+
* {cmp a, b; load 1; load 0} → simplified when used in branch
912+
* The comparison already produces 0 or 1, constants may be redundant
913+
*
914+
* Pattern 5: Consecutive loads that can be combined
915+
* {load r1, [base+off1]; load r2, [base+off2]; op r3, r1, r2}
916+
* Useful for struct member access patterns
917+
* Needs alignment checking and architecture support.
918+
*
919+
* Pattern 6: Load-Load-Select pattern
920+
* {load r1, c1; load r2, c2; select/cmov based on condition}
921+
* Can optimize by loading only the needed value
922+
* Requires control flow analysis.
923+
*
924+
* Pattern 7: Add-Add-Add chain simplification
925+
* {add r1, r0, c1; add r2, r1, c2; add r3, r2, c3}
926+
* Can be simplified if all are constants
927+
* Requires tracking constant values through the chain.
928+
*
929+
* Pattern 8: Global load followed by immediate use
930+
* {global_load r1; op r2, r1, ...; store r2}
931+
* Track global access patterns
932+
* Could optimize to atomic operations or direct memory ops.
933+
* Needs careful synchronization analysis.
934+
*/
935+
936+
return false;
937+
}
938+
858939
/* Main peephole optimization driver.
859940
* It iterates through all functions, basic blocks, and IR instructions to apply
860941
* local optimizations on adjacent instruction pairs.

0 commit comments

Comments
 (0)