[llvm-dev] Clearing the BSS section
John Criswell via llvm-dev
llvm-dev at lists.llvm.org
Fri Aug 28 08:00:28 PDT 2015
On 8/28/15 10:52 AM, devh8h via llvm-dev wrote:
> Hi,
>
> I am writing a function that clears the BSS section on an Cortex-M4 embedded system.
I assume that, for some reason, the operating system is not
demand-paging in zeroed memory. Is that correct?
>
> The LLVM (version 3.7.0rc3) code I had wrote is :
> ;------------
> target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
> target triple = "thumbv7em-none--eabi"
>
> @__bss_start = external global i32
> @__bss_end = external global i32
>
> define void @clearBSS () nounwind {
> entry:
> br label %bssLoopTest
>
> bssLoopTest:
> %p = phi i32* [@__bss_start, %entry], [%p.next, %bssLoop]
> %completed = icmp eq i32* %p, @__bss_end
> br i1 %completed, label %clearCompleted, label %bssLoop
>
> bssLoop:
> store i32 0, i32* %p, align 4
> %p.next = getelementptr inbounds i32, i32* %p, i32 1
> br label %bssLoopTest
>
> clearCompleted:
> ret void
> }
> ;------------
>
> This code runs. But when I optimize it with :
> opt -disable-simplify-libcalls -Os -S source.ll -o optimized.ll
>
> I get the following code for the @clearBSS function :
> ;------------
> define void @clearBSS() nounwind {
> entry:
> br label %bssLoop
>
> bssLoop: ; preds = %entry, %bssLoop
> %p1 = phi i32* [ @__bss_start, %entry ], [ %p.next, %bssLoop ]
> store i32 0, i32* %p1, align 4
> %p.next = getelementptr inbounds i32, i32* %p1, i32 1
> %completed = icmp eq i32* %p.next, @__bss_end
> br i1 %completed, label %clearCompleted, label %bssLoop
>
> clearCompleted: ; preds = %bssLoop
> ret void
> }
> ;------------
> The optimizer has transformed the while loop into a repeat until.
>
> I think it assumes the two variables @__bss_start and @__bss_end are distinct. But they are solved at link time, and they are the same if the BSS section is empty : in this case, the optimized function fails.
>
> Is there a way to prevent the optimizer to assume the two variables are distinct ? Or what is the proper way to deal with link time values ?
Have you tried using the memset intrinsic? You could case bss_start and
bss_end to integers, subtract them to find the length, and then use
memset to zero the memory. I would think memset should work if the
length is zero.
Regards,
John Criswell
>
> Thanks,
>
> Pierre Molinaro
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
John Criswell
Assistant Professor
Department of Computer Science, University of Rochester
http://www.cs.rochester.edu/u/criswell
More information about the llvm-dev
mailing list