Stream: t-compiler/wg-llvm

Topic: basic `#[target_feature]` optimizations


gnzlbg (Jul 27 2019 at 11:10, on Zulip):

@Nikita Popov I was thinking of taking a stab at this: https://bugs.llvm.org/show_bug.cgi?id=41138

gnzlbg (Jul 27 2019 at 11:13, on Zulip):

A super common problem users using the core::arch intrinsics have is that, when abstracting over the intrinsics, they put them behind functions that aren't #[target_feature]. This prevents inlining - inlining across different target features is a bad idea -, which ends up meaning that, e.g., SIMD vectors end up spilled to the stack across each intrinsic

gnzlbg (Jul 27 2019 at 11:14, on Zulip):

I think that even the most basic LLVM pass here would be incredibly valuable

gnzlbg (Jul 27 2019 at 11:17, on Zulip):

If a function is called unconditionally, and that function has target features, add those target features to the caller.

gnzlbg (Jul 27 2019 at 11:18, on Zulip):

recursively traversing all functions, updating their target features through the call stack

Zoxc (Jul 27 2019 at 11:27, on Zulip):

The intrinsics shouldn't have #[target_feature], and should always be inlined

Zoxc (Jul 27 2019 at 11:33, on Zulip):

At least if LLVM handles them correctly, which I hope it does since C/C++ does not have a target_feature feature.

gnzlbg (Jul 27 2019 at 11:35, on Zulip):

If the intrinsics don't have #[target_feature] then they generate incorrect codegen

gnzlbg (Jul 27 2019 at 11:35, on Zulip):

@Zoxc of course C and C++ have a target-feature feature __((target_feature = "foo"))__ or something like that

gnzlbg (Jul 27 2019 at 11:35, on Zulip):

whether the intrinsics should be inlined is also up to the optimizer

gnzlbg (Jul 27 2019 at 11:36, on Zulip):

some of them are quite complex and not worth inlining

Zoxc (Jul 27 2019 at 11:36, on Zulip):

Why do they generate incorrect code? That makes no sense

nagisa (Jul 27 2019 at 12:13, on Zulip):

The pass you likely want to change is the functionattrs pass.

nagisa (Jul 27 2019 at 12:13, on Zulip):

Actually no, you want traversion in a reversed order than what functionattrs does.

nagisa (Jul 27 2019 at 12:14, on Zulip):

Wait, no, from your description it appears that functionattrs is exactly what you want

gnzlbg (Jul 27 2019 at 12:27, on Zulip):

@nagisa the pass needs to track whether it has already been applied to a function, and when it sees an unconditonal function call, if it hasn't been applied to it, then recurse down first

nagisa (Jul 27 2019 at 12:27, on Zulip):

If a function is called unconditionally, and that function has target features, add those target features to the caller.

Is what functionattrs will allow you to implement

nagisa (Jul 27 2019 at 12:28, on Zulip):

this is the same thing it does for readnone/readonly/etc attributes.

gnzlbg (Jul 27 2019 at 12:28, on Zulip):

Why do they generate incorrect code? That makes no sense

@Zoxc Because if they don't have target-features, the llvm intrinsics they call cannot be inlined across them, and everything gets spilled to the stack

nagisa (Jul 27 2019 at 12:28, on Zulip):

i.e. this pass goes from leaves of the trees up to the root (main).

gnzlbg (Jul 27 2019 at 12:28, on Zulip):

@nagisa perfect, that's exactly what i need here

gnzlbg (Jul 27 2019 at 12:29, on Zulip):

i'm not sure if I should duplicate the pass, or modify it

gnzlbg (Jul 27 2019 at 12:30, on Zulip):

I can add options to it, I think i will do that first

nagisa (Jul 27 2019 at 12:33, on Zulip):

It depends on whether it makes sense to have this pass separately enabled from the rest of the stuff functionattrs do.

nagisa (Jul 27 2019 at 12:33, on Zulip):

(likely not)

gnzlbg (Jul 27 2019 at 12:33, on Zulip):

i think that this pass is always sound

gnzlbg (Jul 27 2019 at 12:40, on Zulip):

I'm just afraid that C code is not, and that this pass will break it hard

nagisa (Jul 27 2019 at 12:56, on Zulip):

LLVM does not concern itself with code that’s UB.

Nikita Popov (Jul 27 2019 at 13:12, on Zulip):

LLVM is moving to the Attributor framework (https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/IPO/Attributor.cpp) for attribute inference. I'm not totally sure what the current state there is and whether new additions to FunctionAttrs are accepted at this point.

Nikita Popov (Jul 27 2019 at 13:23, on Zulip):

To propagate target features you need that every path from the entry is guaranteed to hit a target feature call -- which is usually approximated as it being in the entry block and having only guaranteed-transfer instructions before it.

gnzlbg (Jul 27 2019 at 13:32, on Zulip):

I was looking at the attributor framework, and at the Attribute class, but it is not clear to me how target-specific attributes are handled there

gnzlbg (Jul 27 2019 at 13:39, on Zulip):

@Nikita Popov is it possible to iterate over all calls that are guaranteed to be hit from the entry ?

gnzlbg (Jul 27 2019 at 13:43, on Zulip):

i'm not sure whether attributor or FunctionAttrs is a better place for the pass

gnzlbg (Jul 27 2019 at 13:43, on Zulip):

AFAICT attributor would try to recompute the target-feature attribute of a function until a fix-point is reached

gnzlbg (Jul 27 2019 at 13:44, on Zulip):

i'm not sure from reading into the framework whether the attribute of the functions being called are computed before those of the callee or not

gnzlbg (Jul 27 2019 at 13:49, on Zulip):

and indeed the functionality of the FunctionAttributes appears to be replicated in Attributor already

Nikita Popov (Jul 27 2019 at 14:37, on Zulip):

I don't think there's anything for the guaranteed-execution case yet -- a good starting point would be to loop over the instructions in the entry block until isGuaranteedToTransferExecutionToSuccessor() returns false. May be enhanced by checking in-flight attributes (like willreturn), which is where the fixpoint iteration comes in, as you will now depend on the overall attributor state.

Nikita Popov (Jul 29 2019 at 20:10, on Zulip):

@gnzlbg It looks like the necessary tooling for this is being worked on right now (see for example https://reviews.llvm.org/D65186 and https://reviews.llvm.org/D65402), so it probably makes sense to wait a bit until it is in place.

gnzlbg (Jul 30 2019 at 10:09, on Zulip):

Thanks, it appears that jdoerfert is the person to ping about this.

gnzlbg (Jul 30 2019 at 10:10, on Zulip):

It's also unclear to me how to access target-specific attributes from the Attributor framework

Last update: Nov 15 2019 at 09:50UTC