[cfe-dev] questions about expansion of builtins.
Eric Christopher
echristo at gmail.com
Fri Sep 20 16:01:12 PDT 2013
On Fri, Sep 20, 2013 at 2:50 PM, Iain Sandoe <iain at codesourcery.com> wrote:
> Hello Eric,
>
> On 20 Sep 2013, at 22:17, Eric Christopher wrote:
>
>> I'd probably expect to lower builtins to multiple basic blocks in the
>> backend if they needed to do so…
>
> Perhaps, then, I'm missing an alternate solution,
> we wanted to expand in the FE to expose operands to opportunities for scalarisation etc.
> (that, in particular, is an important optimisation for the target)
>
> - so am I attempting something unsupported?
>
No, you should be able to do it, I guess it depends upon the type of
builtins you're expanding. You can generate code in CGBuiltin.cpp
however you'd like though.
-eric
> Iain
>
>> On Fri, Sep 13, 2013 at 12:19 PM, Iain Sandoe <iain at codesourcery.com> wrote:
>>> Hello folks,
>>>
>>> I am working on an out-of-tree port that would, for some cases, like to expand builtins to multiple BBs.
>>>
>>> So far, I've not succeeded in finding any guidance other than the code in CGBuiltin.cpp, Builtin.def, SemaChecking.cpp etc. (specifically, there doesn't appear to be anything in the internals doc.)
>>>
>>> For simple builtins that, effectively, just pass the buck to LLVM for expansion at lower-to-asm time everything works fine. The problems start when they generate BBs as part of the expansion.
>>>
>>> ----
>>>
>>> To try and understand things better, I made a simplistic example "__factorial()" built-in that should be applicable to any port.
>>>
>>> The code for this is attached, along with a driver program; this is set up for X86 so that folks can explore it for themselves [perhaps also this might form the basis of a documentation example, if appropriate]. The CG follows, I hope, the advice of the FE tutorial, although - of course - it could be missing some vital point …
>>>
>>> ----
>>>
>>> OK, so having established that the example is trivial and only intended for illustration; nevertheless, it does exhibit the same issues I see with my real-world builtins.
>>>
>>> Note also that, while one could just as well replace the trivial example here with an inlined function, that is not true of the 'real-world' built-ins I'm trying to expand (part of the job is to overload the CG for different operand types).
>>>
>>> ----
>>>
>>> What I find is that for -O0/O1 the CG behaves as expected - producing (at O1) what looks like correct (and is functional) IR to me:
>>>
>>> ; Function Attrs: noinline nounwind readnone ssp uwtable
>>> define i32 @foo(i32 %x) #0 {
>>> entry:
>>> %nothing.to.do = icmp ult i32 %x, 2
>>> %init.res = select i1 %nothing.to.do, i32 1, i32 %x
>>> br i1 %nothing.to.do, label %finished, label %fact_loop
>>>
>>> fact_loop: ; preds = %entry, %fact_loop
>>> %arg.0 = phi i32 [ %fact.prod, %fact_loop ], [ %init.res, %entry ]
>>> %tmp.0 = phi i32 [ %tmp.dec, %fact_loop ], [ %x, %entry ]
>>> %tmp.dec = add i32 %tmp.0, -1
>>> %fact.prod = mul i32 %tmp.dec, %arg.0
>>> %done = icmp ult i32 %tmp.dec, 2
>>> br i1 %done, label %finished, label %fact_loop
>>>
>>> finished: ; preds = %fact_loop, %entry
>>> %arg.1 = phi i32 [ %init.res, %entry ], [ %fact.prod, %fact_loop ]
>>> ret i32 %arg.1
>>> }
>>>
>>> ==== problems:
>>>
>>> (1) If I try to compile with debug enabled (regardless of optimisation level) I get:
>>>
>>> $ ./Debug+Asserts/bin/clang ../fract.c -g -emit-llvm -S
>>> Assertion failed: (unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() && "Invalid ScopeIdx!"), function getScopeAndInlinedAt, file /Volumes/sc2_src/llvm-trunk/lib/IR/DebugLoc.cpp, line 60.
>>> 0 clang 0x00000001031b721b llvm::sys::PrintStackTrace(__sFILE*) + 38
>>>
>>> (2) If I try to compile -O2, then I get:
>>>
>>> $ ./Debug+Asserts/bin/clang ../fract.c -O2 -emit-llvm -S
>>> Assertion failed: (LHS->getType() == RHS->getType() && "Equality but unequal types!"), function propagateEquality, file /Volumes/sc2_src/llvm-trunk/lib/Transforms/Scalar/GVN.cpp, line 2045.
>>> 0 clang 0x000000010bac521b llvm::sys::PrintStackTrace(__sFILE*) + 38
>>>
>>> Neither case is proving tractable to analysis (at least by me) mainly, because I'm not sure what the "correct" scenario should be.
>>>
>>> ===== Initial questions:
>>>
>>> (of course, any pointers to mistakes in my coding assumptions equally welcome).
>>>
>>> 1. Is it reasonable to expect to be able to expand a built-in in this manner?
>>>
>>> 2. Is there some decoration (for debug at least) needed to label the expansion as belonging to the function that has, effectively, become inlined?
>>>
>>> 3. Any hints about where to start with the O2 problem would be appreciated - although there seems little point in persuing that until 1 and 2 are resolved.
>>>
>>> Thanks,
>>> Iain
>>>
>>> The patch applies to TOT as of 2 hrs ago.
>>> if one does "clang fract.c -O1 -o fract " [-O0 or -O1] then it should produce a working code - at least on x86.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>
More information about the cfe-dev
mailing list