def __init__(self, compsym): self.compsym = compsym ordset = common.OrderedSet self.enumvars = ordset() self.enumlocals = ordset() self.enumparams = ordset() self.setparams = ordset() compnode = compsym.defnode.value posvars = set() negvars = set() # Check for bad patterns in enumerators. kinds = itertools.chain(*dka.findNodeTypes(compnode.enums)) if dha.PatExpr in kinds or dha.PatIgnore in kinds: raise CompError('Invalid enumerator pattern') # Gather enumeration variables and iterated sets. for enum in compnode.enums: self.setparams.add(enum.iter) syms = st.gatherSymbols(enum.target) self.enumvars.update(syms) if dha.isPosEnum(enum): posvars.update(syms) else: negvars.update(syms) # Check that iterated sets are not enumeration variables. if set(self.setparams) & set(self.enumvars): raise CompError('Set parameters may not be enumeration variables') # Check safeness. if not negvars.issubset(posvars): raise CompError('Unsafe negation') # Check that result and condition expressions use only # enumeration variables. rescondvars = set() rescondvars.update(st.gatherSymbols(compnode.elt)) rescondvars.update(itertools.chain( *(st.gatherSymbols(cond) for cond in compnode.conds))) if not rescondvars.issubset(self.enumvars): raise CompError('Invalid dependency on non-enum vars ' 'in result or condition expression') # Separate locals from parameter enumvars. compscope = st.getNodeScope(compnode) for var in self.enumvars: if (compscope.immediateLookupSymbol(var.name, st.KIND_VSYM) is not None): self.enumlocals.add(var) else: self.enumparams.add(var)
def helper(self, target, id): syms = st.gatherSymbols(target) newtarget = du.genDPatTuple([dha.PatVar(s, dha.P_UNKNOWN) for s in syms]) # Generate wildcard comprehension. elt = du.genDTuple([dha.Name(s) for s in syms]) enumtarget = dka.copy(target) st.cleanPatterns(enumtarget) WildcardFiller().run(enumtarget) enum = dha.RelEnum(enumtarget, id) comp = dha.RelSetComp(elt, [enum], [], dka.Symtab()) num = next(wildcard_uid) repldict = {s: dha.VSymbol(s.name + '_W' + num) for s in syms} st.replaceSymbols(comp, repldict) newid = dha.VSymbol(id.name + '_W' + num) invdef = dha.InvDef(newid, comp) ### Need a more robust way to do this part. oldccb = self.code_callback newccb = \ (lambda ccb: oldccb(ccb) + [invdef] if ccb is self.CCB_NORMAL or ccb is self.CCB_LOOP_ENTRY else []) return newtarget, newid, newccb
def genTagInfo(comp): info = comp.info compnode = comp.getCompNode() uset = info.uset if uset is None: return enums = compnode.enums assert(enums[0].iter is uset) rootsyms = set(st.gatherSymbols(enums[0].target)) unconsparams = info.unconsparams assert(rootsyms == set(unconsparams)) taginfo = TagInfo() info.taginfo = taginfo taginfo.compinfo = info pairenums = enums[1:] taginfo.As = As = [] taginfo.Bs = Bs = [] taginfo.Rs = Rs = [] taginfo.DRs = DRs = [] for i, enum in enumerate(pairenums): dka.assertnodetype(enum.target, dha.PatTuple) elts = enum.target.elts assert(len(elts) == 2) dka.assertnodetype(elts[0], dha.PatVar) dka.assertnodetype(elts[1], dha.PatVar) cont, elem = elts[0].id, elts[1].id rel = enum.iter As.append(cont) Bs.append(elem) Rs.append(rel) demrel = TagSym('Dm_' + info.compsym.id + '_' + str(i+1)) DRs.append(demrel) taginfo.tagcomps = tagcomps = [] # Generate auxiliary demand comprehensions. for i, (a, b, r, dr) in enumerate(zip(As, Bs, Rs, DRs)): tagenums = [] # Add U pred. if a in unconsparams: k = unconsparams.index(a) ig1 = [dha.PatIgnore() for z in range(0, i)] ig2 = [dha.PatIgnore() for z in range(i+1, len(unconsparams))] tup = du.genDPatTuple(ig1 + [dha.genUnboundVar(a)] + ig2) e = dha.Enum(tup, uset) tagenums.append(e) # Add other preds. for a2, b2, r2, dr2 in list(zip(As, Bs, Rs, DRs))[:i]: if b2 is a: tup = dha.PatTuple([dha.PatIgnore(), dha.genUnboundVar(b2)]) e = dha.Enum(tup, dr2) tagenums.append(e) # Add orig relation. assert(len(tagenums) > 0) tup = dha.PatTuple([dha.genUnboundVar(a), dha.genUnboundVar(b)]) e = dha.Enum(tup, r) tagenums.append(e) comp = dha.SetComp(dha.Tuple([dha.Name(a), dha.Name(b)]), tagenums, None, dka.Symtab()) instmapping = {s: dha.VSymbol(s.name + '_t' + str(i)) for s in set(As) | set(Bs)} st.replaceSymbols(comp, instmapping) compdef = dha.SetCompDef(dr, comp) tagcomps.append(compdef) return taginfo
def enumsToClauses_reordered(enums, cond, body, boundsyms): ENUM = 'ENUM' COND = 'COND' boundsyms = set(boundsyms) alltargetsyms = set() enum_list = [] for e in enums: targetsyms = set(st.gatherSymbols(e.target)) alltargetsyms |= targetsyms unboundsyms = targetsyms - boundsyms isfield = (hasattr(e.iter, 'isfieldset') and dka.hasnodetype(e.target, dha.PatTuple) and len(e.target.elts) == 2 and dka.hasnodetype(e.target.elts[0], dha.PatVar)) isfieldfirst = e.target.elts[0].id if isfield else None if isfieldfirst is not None and isfieldfirst in boundsyms: unboundsyms = set() enum_list.append((e, targetsyms, unboundsyms, isfieldfirst)) if cond: condhandled = False condsyms = set(st.gatherSymbols(cond)) & alltargetsyms # print('---') # for e, t, u in enum_list: # print(dha.genSyntax(e) + ': ' + ', '.join(s.name for s in t) + # ' (' + ', '.join(s.name for s in u) + ') ' + str(len(u))) # if cond: # print('condsyms: ' + ', '.join(s.name for s in condsyms)) # print('---') sorted_clauses = [] # Trying to add... # Hack heuristic: prefer orders that, when given the choice, # go up using the most recently added clause (depth first). def clauseorder(elem): return len(elem[2]) while len(enum_list) > 0: if cond and not condhandled and len(condsyms) == 0: sorted_clauses.append((COND, cond)) condhandled = True else: copyel = list(enumerate(enum_list)) copyel.sort(key = lambda elem: clauseorder(elem[1])) # enum_list.sort(key = clauseorder) # e, ts, us, isff = enum_list[0] e, ts, us, isff = copyel[0][1] sorted_clauses.append((ENUM, e)) for i, (e2, ts2, us2, isff2) in copyel[1:]: us2.difference_update(ts) if isff2 is not None and isff2 in ts: us2.clear() if cond and not condhandled: condsyms.difference_update(ts) enum_list.pop(copyel[0][0]) if cond and not condhandled: sorted_clauses.append((COND, cond)) condhandled = True # print('---') # for k, e in sorted_clauses: # print(k + ': ' + dha.genSyntax(e)) # print('---') code = body for k, cl in reversed(sorted_clauses): if k is COND: code = [dha.If([dha.CondCase(cl, dha.Block(code))])] elif k is ENUM: code = enumToClause(cl, dha.Block(code)) else: assert() return code