Skip to content

Blockfill optimization fixes potpourri #493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions backends/asm/optimize_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,6 +2353,12 @@ FindPrevSetterForReplace(IR *irorig, Operand *dst)
#endif
if (SrcOnlyHwReg(dst))
return NULL;

unsigned check_flags = FlagsUsedByCond(irorig->cond);
// Currently flags_safe makes some functions worse
// Because dead sets can't be eliminated correctly in conditional sequences
bool flags_safe = curfunc->optimize_flags & OPT_EXPERIMENTAL;

for (ir = irorig->prev; ir; ir = ir->prev) {
if (IsDummy(ir)) {
continue;
Expand All @@ -2368,8 +2374,12 @@ FindPrevSetterForReplace(IR *irorig, Operand *dst)
if (IsCallThatUsesReg(ir,dst)) {
return NULL;
}
if (InstrSetsFlags(ir,check_flags)) {
// This needs to go first, since the set IR also setting flags is unsafe
flags_safe = false;
}
if (ir->dst == dst && (InstrSetsDst(ir) || ir->opc == OPC_TEST || ir->opc == OPC_TESTBN)) {
if (ir->cond != COND_TRUE) {
if (flags_safe ? !CondIsSubset(ir->cond,irorig->cond) : ir->cond != COND_TRUE) {
// cannot be sure that we set the value here,
// since the set is conditional
return NULL;
Expand Down Expand Up @@ -5276,9 +5286,18 @@ OptimizeLongfill(IRList *irl) {
IR *prevset;
int32_t setval;
if (IsDummy(ir)) continue;
if (ir->opc == OPC_CALL && !CondIsSubset(COND_C,ir->cond) && !strcmp(ir->dst->name,"builtin_longfill_")
if (ir->opc == OPC_CALL && CondIsSubset(ir->cond,(IRCond)((ir->cond>>2)|COND_NC)) && !strcmp(ir->dst->name,"builtin_longfill_")
&& (prevset = FindPrevSetterForReplace(ir,GetArgReg(1)))
&& isConstMove(prevset,&setval)) {

// The CondIsSubset(ir->cond,(ir->cond>>2)|COND_NC)
// bit above requires explanation:
// Some conditions can't be combined with COND_NC.
// Those are the ones where there are some condition states(of the 4 possible)
// that execute the orignal condition,
// but after clearing C do not neccessarily execute the combined condition
// The bitwise operation is somewhat mindboggling.

int addr = ir->addr; // Some opts require addresses to be sorta-correct;
// Since we replace a funccall, we can clobber flags and args
IR *sub = NewIR(OPC_SUB);
Expand All @@ -5288,9 +5307,8 @@ OptimizeLongfill(IRList *irl) {
sub->addr = addr;
sub->cond = ir->cond;
IR *setq = NewIR(OPC_SETQ);
setq->cond = COND_NC;
setq->dst = GetArgReg(2);
setq->cond = (IRCond)(COND_NC | ir->cond);
setq->dst = GetArgReg(2);
setq->addr = addr;
IR *wrlong = NewIR(OPC_WRLONG);
wrlong->cond = (IRCond)(COND_NC | ir->cond);
Expand Down Expand Up @@ -5352,9 +5370,7 @@ OptimizeIRLocal(IRList *irl, Function *f)

// multiply divide optimization need only be performed once,
// and should be done before other optimizations confuse things
OptimizeMulDiv(irl);
// Similarily for longfill (opt can only become available from inlining)
OptimizeLongfill(irl);
OPT_PASS(OptimizeMulDiv(irl));
again:
do {
change = 0;
Expand Down Expand Up @@ -5396,6 +5412,7 @@ OptimizeIRLocal(IRList *irl, Function *f)
OPT_PASS(OptimizeP2(irl));
}
if (gl_p2) {
OPT_PASS(OptimizeLongfill(irl));
OPT_PASS(FixupLoneCORDIC(irl));
if (flags & OPT_CONST_PROPAGATE) {
OPT_PASS(CORDICconstPropagate(irl));
Expand Down
7 changes: 2 additions & 5 deletions sys/gcalloc.spin
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,8 @@ pri _gc_doalloc(size, reserveflag) : ptr | zptr

if ptr
' zero the returned memory
size := ((size << pagesizeshift) - headersize)/4
zptr := ptr ' skip the header
repeat size
long[zptr] := 0
zptr += 4
size := ((size << pagesizeshift) - headersize)+/4
longfill(ptr,0,size)
return ptr

'
Expand Down
Loading
Loading