# HG changeset patch # User Michael Pavone # Date 1739864436 28800 # Node ID cbd54de385d3e90998631024896f4796fd0ac6cd # Parent c5314c0779c28b5ca632d206229bd782ac96eaf6 Fix some issues with constant folding in CPU DSL diff -r c5314c0779c2 -r cbd54de385d3 cpu_dsl.py --- a/cpu_dsl.py Mon Feb 17 23:40:14 2025 -0800 +++ b/cpu_dsl.py Mon Feb 17 23:40:36 2025 -0800 @@ -1297,18 +1297,53 @@ procParams = [] allParamsConst = flagUpdates is None and not prog.conditional opDef = _opMap.get(self.op) - for param in self.params: - isDst = (not opDef is None) and len(procParams) in opDef.outOp - allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues - if isDst and self.op == 'xchg': - #xchg uses its regs as both source and destination - #we need to resolve as both so that disperse/coalesce flag stuff gets done - prog.resolveParam(param, parent, fieldVals, allowConst, False) - param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) - - if (not type(param) is int) and len(procParams) != len(self.params) - 1: + if self.op == 'xchg': + #xchg uses its regs as both source and destination + #we need to resolve as both so that disperse/coalesce flag stuff gets done + #it also interacts weirdly with constant folding + a = prog.resolveParam(self.params[0], parent, fieldVals, True, False) + b = prog.resolveParam(self.params[1], parent, fieldVals, True, False) + dsta = prog.resolveParam(self.params[0], parent, fieldVals, False, True) + dstb = prog.resolveParam(self.params[1], parent, fieldVals, False, True) + dsta_nocontext = dsta[len("context->"):] if dsta.startswith('context->') else dsta + dstb_nocontext = dstb[len("context->"):] if dstb.startswith('context->') else dstb + if type(a) is int: + if type(b) is int: + #both params are constant, fold + parent.regValues[dsta_nocontext] = b + parent.regValues[dstb_nocontext] = a + if prog.isReg(dsta_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + if prog.isReg(dstb_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + else: + parent.regValues[dstb_nocontext] = a + del parent.regValues[dsta_nocontext] + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + if prog.isReg(dstb_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + prog.lastOp = self + return + elif type(b) is int: + parent.regValues[dsta_nocontext] = b + del parent.regValues[dstb_nocontext] + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + if prog.isReg(dsta_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + prog.lastOp = self + return + else: + procParams = [dsta, dstb] allParamsConst = False - procParams.append(param) + else: + for param in self.params: + isDst = (not opDef is None) and len(procParams) in opDef.outOp + allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues + param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) + + if (not type(param) is int) and len(procParams) != len(self.params) - 1: + allParamsConst = False + procParams.append(param) if prog.needFlagCoalesce: output.append(prog.flags.coalesceFlags(prog, otype)) prog.needFlagCoalesce = False @@ -1355,7 +1390,14 @@ dst = prog.meta[dst] if dst in parent.regValues: del parent.regValues[dst] - + if self.op in ('ocall', 'ccall', 'pcall'): + #we called in to arbitrary C code, assume any reg could have changed + to_clear = [] + for name in parent.regValues: + if prog.isReg(name): + to_clear.append(name) + for name in to_clear: + del parent.regValues[name] elif self.op in prog.subroutines: procParams = [] for param in self.params: @@ -2138,6 +2180,8 @@ if isdst: self.lastDst = param self.lastSize = None + if allowConstant and maybeLocal in parent.regValues: + return parent.regValues[maybeLocal] return maybeLocal if param in fieldVals: param = fieldVals[param]