Hi, I want to ensure that when a specific TE schedule is used during compilation, LLVM codegen inserts a function-level attribute on the resulting LLVM function that is generated. Currently I’ve been doing this by inserting a pragma on the outer loop of the schedule where it can then be picked up in LLVM codegen and added to the current function being codegenned. I’ve tried to illustrate this below with a trimmed down (non-runnable) example:
TE schedule:
def my_schedule(outs):
sched = te.create_schedule([x.op for x in outs])
def _callback(op):
a = sched[op].op.axis
sched[op].pragma(a, "my_function_attribute")
traverse_inline(sched, outs[-1].op, _callback)
return sched
Scheduled TIR:
@T.prim_func
def tvmgen_default(in: T.Buffer((64, 32), "float32"), out: T.Buffer((64, 128), "float32")):
T.func_attr({"from_legacy_te_schedule": T.bool(True), "global_symbol": "tvmgen_default", "tir.noalias": T.bool(True)})
compute = T.allocate([4096], "float32", "global")
compute_1 = T.Buffer((4096,), data=compute)
for a in range(4):
a = T.int32()
T.attr(T.iter_var(a, None, "DataPar", ""), "pragma_my_function_attribute")
...(do something useful)...
This pragma can then be picked up during codegen by visiting each AttrStmtNode and the LLVM function attribute can be added to the function currently being generated:
void CodeGenCPU::VisitStmt_(const AttrStmtNode* op) {
String attr_key = op->attr_key;
if (tir::attr::IsPragmaKey(attr_key)) {
if (attr_key == "pragma_my_function_attribute") {
function_->addFnAttr("my_function_attribute");
this->VisitStmt(op->body);
}
} else {
CodeGenLLVM::VisitStmt_(op);
}
}
This works well and it achieves the desired result, however it seems to me to be more of a hack. My thinking is that pragmas operate at the loop level, while I want to add annotations at the function level. A motivating example for adding LLVM function attributes in the first place can be found here.
Adding the attribute to T.func_attr({"from_legacy_te_schedule": T.bool(True), "global_symbol": "tvmgen_default", "tir.noalias": T.bool(True)})
and picking that up in the LLVM codegen backend makes more sense to me, however, I wasn’t able to find a way to make changes to func_attr
from within TE.
Curious if anyone has experienced similar issues or if there are any approaches I’ve not considered? I’m fairly new to TE/TIR so any suggestions are welcome