Abstract Code (icode)
program(
chain(
func(TVoid, "init", [ ],
chain()
),
func(TVoid, "transform", [ Y, X ],
decl([ t57, t58, t59, t60, t61, t62, t63, t64 ],
chain(
assign(t57, add(deref(X), deref(add(X, V(4))))),
assign(t58, add(deref(add(X, V(1))), deref(add(X, V(5))))),
assign(t59, sub(deref(X), deref(add(X, V(4))))),
assign(t60, sub(deref(add(X, V(1))), deref(add(X, V(5))))),
assign(t61, add(deref(add(X, V(2))), deref(add(X, V(6))))),
assign(t62, add(deref(add(X, V(3))), deref(add(X, V(7))))),
assign(t63, sub(deref(add(X, V(2))), deref(add(X, V(6))))),
assign(t64, sub(deref(add(X, V(3))), deref(add(X, V(7))))),
assign(deref(Y), add(t57, t61)),
assign(deref(add(Y, V(1))), add(t58, t62)),
assign(deref(add(Y, V(4))), sub(t57, t61)),
assign(deref(add(Y, V(5))), sub(t58, t62)),
assign(deref(add(Y, V(2))), sub(t59, t64)),
assign(deref(add(Y, V(3))), add(t60, t63)),
assign(deref(add(Y, V(6))), add(t59, t64)),
assign(deref(add(Y, V(7))), sub(t60, t63))
)
)
)
)
)
Basics
c1 := skip(); # NOP
a := var.fresh_t("j", TInt); # create a "fresh" variable
c2 := assign(a, V(0)); # assignment
c3 := assign(a, fcall("foo")); # call to foo()
c4 := chain(c1, c2, c3); # basic block
i := Ind(4); # loop index
c5 := loop(i, 4, c4); # loop
c6 := decl([a], c5); # declare a variable
PrintCode("", c6, SpiralDefaults); # pretty print as C code
Internal Fields
a.id; a.t;
c2.exp; c2.loc;
c3.cmds;
c4.var; c4.range; c4.cmd;
c5.vars; c5.cmd;
Arrays and Pointers
X; # default input
Y; # default output
X.t; Y.t; # they are pointers
deref(X + V(4)); # *(X+4)
t := var.fresh_t("t", TArray(TReal, 4)); # double[4]
nth(t, V(2)); # T[2]
tcast(TInt, deref(X + V(4))); # typecast
Constants
d := var.fresh_t("D", TReal); # data variable
v := V(1.1); # value
c := data(d, v, # declare constant
assign(nth(X, 0), nth(X, 0) * d)
);
Expressions and Commands
# spiral-core\namespaces\spiral\code\ir.gi
Class(neg, AutoFoldExp, rec(
ev := self >> -self.args[1].ev(),
computeType := self >> let(t := self.args[1].t,
Cond(IsPtrT(t),
t.aligned([t.alignment[1],
-t.alignment[2] mod t.alignment[1]]), t)),
));
Class(chain, multiwrap, rec(
isChain := true,
flatten := self >> let(cls := self.__bases__[1],
CopyFields(self, rec(cmds := ConcatList(self.cmds,
c -> Cond(IsChain(c) and not IsBound(c.doNotFlatten),
c.cmds, ObjId(c) = skip, [], [c]))))),
__call__ := meth(arg)
local self, cmds;
[self, cmds] := [arg[1], Flat(Drop(arg, 1))];
return WithBases(self, rec(
operations := CmdOps,
cmds := Checked(ForAll(cmds, IsCommand), cmds)));
end
));
Find All icode Expressions, Types, Commands, Etc.
# all objects defined in spiral.code
allobs := Dir(spiral.code);
# filter function, checking that base classes are in a given list
flt := bl -> (o -> (ForAny(bl, b -> b in let(ob := spiral.code.(o),
When(IsRec(ob) and IsBound(ob.__bases__), ob.__bases__, [])))));
# list all expressions
Filtered(allobs, flt([Exp, AutoFoldExp]));
# list all types
Filtered(allobs, flt([AtomicTyp]));
# list all commands
Filtered(allobs, flt([Command]));