[LLVMdev] Documentation about converting GIMPLE IR to LLVM IR in LLVM-GCC/DragonEgg

Duncan Sands baldrick at free.fr
Thu Jul 12 07:18:35 PDT 2012


Hi Mahesha,
> I am trying to understand the process followed for converting GIMPLE IR to LLVM
> IR in LLVM-GCC/DragonEgg - more importantly conversion of OpenMP extended GIMPLE
> IR to LLVM IR. It would be great if anybody points me to some documentation
> before I my-self delve into the understanding of related source code.

dragonegg doesn't have to do anything special for openmp, since gcc has already
lowered it to a bunch of extra functions and library calls by that point.

Ciao, Duncan.

PS: Here's an example:

void foo()
{
   int i;

   #pragma omp parallel
     {
     #pragma omp parallel
       {
       #pragma omp parallel
         {
           i++;
         }
       }
     }
}

-> (the LLVM IR is a direct transliteration of the gimple):

target datalayout = 
"e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

module asm "\09.ident\09\22GCC: (GNU) 4.7.1 20120603 (prerelease) LLVM: 3.2svn\22"

%struct..omp_data_s.2 = type { i32* }
%struct..omp_data_s.1 = type { i32* }
%struct..omp_data_s.0 = type { i32 }

define internal void @foo._omp_fn.2(i8* nocapture %.omp_data_i) nounwind uwtable {
entry:
   %0 = bitcast i8* %.omp_data_i to i32**
   %1 = load i32** %0, align 8
   %2 = load i32* %1, align 4
   %3 = add i32 %2, 1
   store i32 %3, i32* %1, align 4
   ret void
}

define internal void @foo._omp_fn.1(i8* nocapture %.omp_data_i) nounwind uwtable {
entry:
   %.omp_data_o.3 = alloca %struct..omp_data_s.2, align 8
   %0 = bitcast i8* %.omp_data_i to i32**
   %1 = load i32** %0, align 8
   %2 = getelementptr inbounds %struct..omp_data_s.2* %.omp_data_o.3, i64 0, i32 0
   store i32* %1, i32** %2, align 8
   %3 = bitcast %struct..omp_data_s.2* %.omp_data_o.3 to i8*
   call void @GOMP_parallel_start(void (i8*)* @foo._omp_fn.2, i8* %3, i32 0) 
nounwind
   call void @foo._omp_fn.2(i8* %3) nounwind uwtable
   call void @GOMP_parallel_end() nounwind
   ret void
}

declare void @GOMP_parallel_start(void (i8*)*, i8*, i32) nounwind

declare void @GOMP_parallel_end() nounwind

define internal void @foo._omp_fn.0(i8* %.omp_data_i) nounwind uwtable {
entry:
   %.omp_data_o.4 = alloca %struct..omp_data_s.1, align 8
   %0 = bitcast i8* %.omp_data_i to i32*
   %1 = getelementptr inbounds %struct..omp_data_s.1* %.omp_data_o.4, i64 0, i32 0
   store i32* %0, i32** %1, align 8
   %2 = bitcast %struct..omp_data_s.1* %.omp_data_o.4 to i8*
   call void @GOMP_parallel_start(void (i8*)* @foo._omp_fn.1, i8* %2, i32 0) 
nounwind
   call void @foo._omp_fn.1(i8* %2) nounwind uwtable
   call void @GOMP_parallel_end() nounwind
   ret void
}

define void @foo(...) nounwind uwtable {
entry:
   %.omp_data_o.5 = alloca %struct..omp_data_s.0, align 8
   %0 = bitcast %struct..omp_data_s.0* %.omp_data_o.5 to i8*
   call void @GOMP_parallel_start(void (i8*)* @foo._omp_fn.0, i8* %0, i32 0) 
nounwind
   call void @foo._omp_fn.0(i8* %0) nounwind uwtable
   call void @GOMP_parallel_end() nounwind
   ret void
}



More information about the llvm-dev mailing list