[DragonEgg] Mysterious FRAME coming from gimple to LLVM

Hi Duncan,

A DragonEgg/GCC-related question: do you know where these strange FRAME tokens originate from (e.g. %struct.FRAME.matmul)? Compiling simple Fortran code with DragonEgg:

cat matmul.f90

subroutine matmul(nx, ny, nz)
implicit none

integer :: nx, ny, nz
real, dimension(nx, ny) :: A
real, dimension(ny, nz) :: B
real, dimension(nx, nz) :: C

integer :: i, j, k
real, volatile :: start, finish

call init_array

call cpu_time(start)

do i = 1, nx
do j = 1, nz
C(i,j) = 0
do k = 1, ny
C(i, j) = C(i, j) + A(i, k) * B(k, j)
enddo
enddo
enddo

call cpu_time(finish)

print *, sum(C), maxval(C), minval(C)
call flush()

contains

subroutine init_array
implicit none

integer :: i, j

do i = 1, nx
do j = 1, ny
A(i, j) = (1 + mod((i * j), 1024)) / 2.0
enddo
enddo

do i = 1, ny
do j = 1, nz
B(i, j) = (1 + mod((i * j), 1024)) / 2.0
enddo
enddo

end subroutine init_array

end subroutine matmul

kernelgen-dragonegg matmul.f90 -o -

; ModuleID = ‘matmul.f90’
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”

%struct.FRAME.matmul = type { i64, i64, [0 x float], i64, i64, i32, i64, i64, [0 x float], i64, i64, i32, i32* }
%struct.__st_parameter_dt = type { %struct.__st_parameter_common, i64, i64*, i64*, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, [256 x i8], i32*, i64, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, i32, i8*, i8*, i32, [4 x i8] }
%struct.__st_parameter_common = type { i32, i32, i8*, i32, i32, i8*, i32* }

@.cst = linker_private constant [11 x i8] c"matmul.f90\00", align 8

define internal void @init_array.1535(%struct.FRAME.matmul* nest %CHAIN.41) nounwind uwtable {
entry:
%CHAIN.41_addr = alloca %struct.FRAME.matmul*, align 8
%i = alloca i32
%j = alloca i32
%D.1539 = alloca i32
%D.1553 = alloca i32
%D.1542 = alloca i32
%D.1552 = alloca i32
%D.1554 = alloca i32
%D.1568 = alloca i32
%D.1557 = alloca i32
%D.1567 = alloca i32
%“alloca point” = bitcast i32 0 to i32
store %struct.FRAME.matmul* %CHAIN.41, %struct.FRAME.matmul** %CHAIN.41_addr
%0 = load %struct.FRAME.matmul** %CHAIN.41_addr, align 64
%“ssa point” = bitcast i32 0 to i32
br label %“2”

“2”: ; preds = %entry
%1 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 12
%2 = load i32** %1, align 8
%3 = load i32* %2, align 4
%4 = icmp sle i32 1, %3
br i1 %4, label %“3”, label %“8”

“3”: ; preds = %“7”, %“2”
%5 = phi i32 [ %33, %“7” ], [ 1, %“2” ]
%6 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 11
%7 = load i32** %6, align 8
%8 = load i32* %7, align 4
%9 = icmp sle i32 1, %8
br i1 %9, label %“4”, label %“6”

“4”: ; preds = %“5”, %“3”
%10 = phi i32 [ %30, %“5” ], [ 1, %“3” ]
%11 = sext i32 %5 to i64
%12 = sext i32 %10 to i64
%13 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 10
%14 = load i64* %13, align 8
%15 = mul i64 %12, %14
%16 = add i64 %11, %15
%17 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 9
%18 = load i64* %17, align 8
%19 = add i64 %16, %18
%20 = mul i32 %5, %10
%21 = srem i32 %20, 1024
%22 = add i32 %21, 1
%23 = sitofp i32 %22 to float
%24 = fdiv float %23, 2.000000e+00
%25 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 8
%26 = load [0 x float]** %25, align 8
%27 = bitcast [0 x float]* %26 to float*
%28 = getelementptr float* %27, i64 %19
store float %24, float* %28, align 4
%29 = icmp eq i32 %10, %8
%30 = add i32 %10, 1
%31 = icmp ne i1 %29, false
br i1 %31, label %“6”, label %“5”

“5”: ; preds = %“4”
br label %“4”

“6”: ; preds = %“4”, %“3”
%32 = icmp eq i32 %5, %3
%33 = add i32 %5, 1
%34 = icmp ne i1 %32, false
br i1 %34, label %“8”, label %“7”

“7”: ; preds = %“6”
br label %“3”

“8”: ; preds = %“6”, %“2”
%35 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 11
%36 = load i32** %35, align 8
%37 = load i32* %36, align 4
%38 = icmp sle i32 1, %37
br i1 %38, label %“9”, label %“14”

“9”: ; preds = %“13”, %“8”
%39 = phi i32 [ %67, %“13” ], [ 1, %“8” ]
%40 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 5
%41 = load i32** %40, align 8
%42 = load i32* %41, align 4
%43 = icmp sle i32 1, %42
br i1 %43, label %“10”, label %“12”

“10”: ; preds = %“11”, %“9”
%44 = phi i32 [ %64, %“11” ], [ 1, %“9” ]
%45 = sext i32 %39 to i64
%46 = sext i32 %44 to i64
%47 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 4
%48 = load i64* %47, align 8
%49 = mul i64 %46, %48
%50 = add i64 %45, %49
%51 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 3
%52 = load i64* %51, align 8
%53 = add i64 %50, %52
%54 = mul i32 %39, %44
%55 = srem i32 %54, 1024
%56 = add i32 %55, 1
%57 = sitofp i32 %56 to float
%58 = fdiv float %57, 2.000000e+00
%59 = getelementptr inbounds %struct.FRAME.matmul* %0, i32 0, i32 2
%60 = load [0 x float]** %59, align 8
%61 = bitcast [0 x float]* %60 to float*
%62 = getelementptr float* %61, i64 %53
store float %58, float* %62, align 4
%63 = icmp eq i32 %44, %42
%64 = add i32 %44, 1
%65 = icmp ne i1 %63, false
br i1 %65, label %“12”, label %“11”

“11”: ; preds = %“10”
br label %“10”

“12”: ; preds = %“10”, %“9”
%66 = icmp eq i32 %39, %37
%67 = add i32 %39, 1
%68 = icmp ne i1 %66, false
br i1 %68, label %“14”, label %“13”

“13”: ; preds = %“12”
br label %“9”

“14”: ; preds = %“12”, %“8”
br label %return

return: ; preds = %“14”
ret void
}

define void @matmul_(i32* noalias %nx, i32* noalias %ny, i32* noalias %nz) nounwind uwtable {
entry:
%nx_addr = alloca i32*, align 8
%ny_addr = alloca i32*, align 8
%nz_addr = alloca i32*, align 8
%ubound.0 = alloca i64
%ubound.1 = alloca i64
%stride.2 = alloca i64
%offset.3 = alloca i64
%size.4 = alloca i64
%a = alloca [0 x float]*
%ubound.5 = alloca i64
%ubound.6 = alloca i64
%stride.7 = alloca i64
%offset.8 = alloca i64
%size.9 = alloca i64
%b = alloca [0 x float]*
%ubound.10 = alloca i64
%ubound.11 = alloca i64
%stride.12 = alloca i64
%offset.13 = alloca i64
%size.14 = alloca i64
%c = alloca [0 x float]*
%finish = alloca float
%i = alloca i32
%j = alloca i32
%k = alloca i32
%start = alloca float
%D.1630 = alloca i64
%D.1631 = alloca i64
%D.1632 = alloca i64
%D.1636 = alloca i64
%D.1637 = alloca i64
%D.1638 = alloca i64
%D.1642 = alloca i64
%D.1643 = alloca i64
%D.1644 = alloca i64
%a.31 = alloca i8*
%D.1645 = alloca i64
%b.34 = alloca i8*
%D.1639 = alloca i64
%c.37 = alloca i8*
%D.1633 = alloca i64
%FRAME.40 = alloca %struct.FRAME.matmul
%D.1582 = alloca i32
%D.1593 = alloca i32
%D.1585 = alloca i32
%D.1592 = alloca i32
%D.1588 = alloca i32
%D.1591 = alloca i32
%dt_parm.15 = alloca %struct.__st_parameter_dt
%D.1604 = alloca float
%D.1598 = alloca i64
%D.1597 = alloca i64
%D.1596 = alloca i64
%val.16 = alloca float
%S.17 = alloca i64
%D.1601 = alloca i64
%S.18 = alloca i64
%D.1616 = alloca float
%fast.21 = alloca i32
%nonempty.20 = alloca i32
%D.1608 = alloca i64
%D.1607 = alloca i64
%D.1606 = alloca i64
%limit.19 = alloca float
%S.22 = alloca i64
%D.1613 = alloca i64
%S.23 = alloca i64
%D.1628 = alloca float
%fast.26 = alloca i32
%nonempty.25 = alloca i32
%D.1620 = alloca i64
%D.1619 = alloca i64
%D.1618 = alloca i64
%limit.24 = alloca float
%S.27 = alloca i64
%D.1625 = alloca i64
%S.28 = alloca i64
%D.1635 = alloca i8*
%D.1641 = alloca i8*
%D.1647 = alloca i8*
%“alloca point” = bitcast i32 0 to i32
store i32* %nx, i32** %nx_addr
store i32* %ny, i32** %ny_addr
store i32* %nz, i32** %nz_addr
%0 = load i32** %nx_addr, align 64
%1 = load i32** %ny_addr, align 64
%2 = load i32** %nz_addr, align 64
%“ssa point” = bitcast i32 0 to i32
br label %“2”

“2”: ; preds = %entry
%3 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 12
store i32* %0, i32** %3, align 8
%4 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 11
store i32* %1, i32** %4, align 8
%5 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 5
store i32* %2, i32** %5, align 8
%6 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 12
%7 = load i32** %6, align 8
%8 = load i32* %7, align 4
%9 = sext i32 %8 to i64
%10 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 6
store i64 %9, i64* %10, align 8
%11 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 6
%12 = load i64* %11, align 8
%13 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
store i64 %12, i64* %13, align 8
%14 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
%15 = load i64* %14, align 8
%16 = icmp sge i64 %15, 0
%17 = select i1 %16, i64 %15, i64 0
%18 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
store i64 %17, i64* %18, align 8
%19 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 11
%20 = load i32** %19, align 8
%21 = load i32* %20, align 4
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 7
store i64 %22, i64* %23, align 8
%24 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
%25 = load i64* %24, align 8
%26 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 7
%27 = load i64* %26, align 8
%28 = mul i64 %25, %27
%29 = icmp sge i64 %28, 0
%30 = select i1 %29, i64 %28, i64 0
%31 = add i64 %30, -1
%32 = mul i64 %30, 32
%33 = mul i64 %30, 4
%34 = mul i64 %30, 4
%35 = icmp uge i64 %34, 1
%36 = select i1 %35, i64 %34, i64 1
%37 = call noalias i8* @malloc(i64 %36) nounwind
%38 = bitcast i8* %37 to [0 x float]*
%39 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 8
store [0 x float]* %38, [0 x float]** %39, align 8
%40 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
%41 = load i64* %40, align 8
%not = xor i64 %41, -1
%42 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 9
store i64 %not, i64* %42, align 8
%43 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 11
%44 = load i32** %43, align 8
%45 = load i32* %44, align 4
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 0
store i64 %46, i64* %47, align 8
%48 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 0
%49 = load i64* %48, align 8
%50 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
store i64 %49, i64* %50, align 8
%51 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
%52 = load i64* %51, align 8
%53 = icmp sge i64 %52, 0
%54 = select i1 %53, i64 %52, i64 0
%55 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
store i64 %54, i64* %55, align 8
%56 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 5
%57 = load i32** %56, align 8
%58 = load i32* %57, align 4
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 1
store i64 %59, i64* %60, align 8
%61 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
%62 = load i64* %61, align 8
%63 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 1
%64 = load i64* %63, align 8
%65 = mul i64 %62, %64
%66 = icmp sge i64 %65, 0
%67 = select i1 %66, i64 %65, i64 0
%68 = add i64 %67, -1
%69 = mul i64 %67, 32
%70 = mul i64 %67, 4
%71 = mul i64 %67, 4
%72 = icmp uge i64 %71, 1
%73 = select i1 %72, i64 %71, i64 1
%74 = call noalias i8* @malloc(i64 %73) nounwind
%75 = bitcast i8* %74 to [0 x float]*
%76 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 2
store [0 x float]* %75, [0 x float]** %76, align 8
%77 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
%78 = load i64* %77, align 8
%not1 = xor i64 %78, -1
%79 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 3
store i64 %not1, i64* %79, align 8
%80 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 12
%81 = load i32** %80, align 8
%82 = load i32* %81, align 4
%83 = sext i32 %82 to i64
%84 = icmp sge i64 %83, 0
%85 = select i1 %84, i64 %83, i64 0
%86 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 5
%87 = load i32** %86, align 8
%88 = load i32* %87, align 4
%89 = sext i32 %88 to i64
%90 = mul i64 %85, %89
%91 = icmp sge i64 %90, 0
%92 = select i1 %91, i64 %90, i64 0
%93 = add i64 %92, -1
%94 = mul i64 %92, 32
%95 = mul i64 %92, 4
%96 = mul i64 %92, 4
%97 = icmp uge i64 %96, 1
%98 = select i1 %97, i64 %96, i64 1
%99 = call noalias i8* @malloc(i64 %98) nounwind
%100 = bitcast i8* %99 to [0 x float]*
%not2 = xor i64 %85, -1
call void @init_array.1535(%struct.FRAME.matmul* nest %FRAME.40) nounwind
call void bitcast (void (…)* @_gfortran_cpu_time_4 to void (float*))(float %start) nounwind
%101 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 12
%102 = load i32** %101, align 8
%103 = load i32* %102, align 4
%104 = icmp sle i32 1, %103
br i1 %104, label %“3”, label %“11”

“3”: ; preds = %“10”, %“2”
%105 = phi i32 [ %175, %“10” ], [ 1, %“2” ]
%106 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 5
%107 = load i32** %106, align 8
%108 = load i32* %107, align 4
%109 = icmp sle i32 1, %108
br i1 %109, label %“4”, label %“9”

“4”: ; preds = %“8”, %“3”
%110 = phi i32 [ %172, %“8” ], [ 1, %“3” ]
%111 = sext i32 %105 to i64
%112 = sext i32 %110 to i64
%113 = mul i64 %112, %85
%114 = add i64 %111, %113
%115 = add i64 %114, %not2
%116 = bitcast [0 x float]* %100 to float*
%117 = getelementptr float* %116, i64 %115
store float 0.000000e+00, float* %117, align 4
%118 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 11
%119 = load i32** %118, align 8
%120 = load i32* %119, align 4
%121 = icmp sle i32 1, %120
br i1 %121, label %“5”, label %“7”

“5”: ; preds = %“6”, %“4”
%122 = phi i32 [ %169, %“6” ], [ 1, %“4” ]
%123 = sext i32 %105 to i64
%124 = sext i32 %110 to i64
%125 = mul i64 %124, %85
%126 = add i64 %123, %125
%127 = add i64 %126, %not2
%128 = sext i32 %105 to i64
%129 = sext i32 %110 to i64
%130 = mul i64 %129, %85
%131 = add i64 %128, %130
%132 = add i64 %131, %not2
%133 = bitcast [0 x float]* %100 to float*
%134 = getelementptr float* %133, i64 %132
%135 = load float* %134, align 4
%136 = sext i32 %105 to i64
%137 = sext i32 %122 to i64
%138 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 10
%139 = load i64* %138, align 8
%140 = mul i64 %137, %139
%141 = add i64 %136, %140
%142 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 9
%143 = load i64* %142, align 8
%144 = add i64 %141, %143
%145 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 8
%146 = load [0 x float]** %145, align 8
%147 = bitcast [0 x float]* %146 to float*
%148 = getelementptr float* %147, i64 %144
%149 = load float* %148, align 4
%150 = sext i32 %122 to i64
%151 = sext i32 %110 to i64
%152 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 4
%153 = load i64* %152, align 8
%154 = mul i64 %151, %153
%155 = add i64 %150, %154
%156 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 3
%157 = load i64* %156, align 8
%158 = add i64 %155, %157
%159 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 2
%160 = load [0 x float]** %159, align 8
%161 = bitcast [0 x float]* %160 to float*
%162 = getelementptr float* %161, i64 %158
%163 = load float* %162, align 4
%164 = fmul float %149, %163
%165 = fadd float %135, %164
%166 = bitcast [0 x float]* %100 to float*
%167 = getelementptr float* %166, i64 %127
store float %165, float* %167, align 4
%168 = icmp eq i32 %122, %120
%169 = add i32 %122, 1
%170 = icmp ne i1 %168, false
br i1 %170, label %“7”, label %“6”

“6”: ; preds = %“5”
br label %“5”

“7”: ; preds = %“5”, %“4”
%171 = icmp eq i32 %110, %108
%172 = add i32 %110, 1
%173 = icmp ne i1 %171, false
br i1 %173, label %“9”, label %“8”

“8”: ; preds = %“7”
br label %“4”

“9”: ; preds = %“7”, %“3”
%174 = icmp eq i32 %105, %103
%175 = add i32 %105, 1
%176 = icmp ne i1 %174, false
br i1 %176, label %“11”, label %“10”

“10”: ; preds = %“9”
br label %“3”

“11”: ; preds = %“9”, %“2”
call void bitcast (void (…)* @_gfortran_cpu_time_4 to void (float*))(float %finish) nounwind
%177 = getelementptr inbounds %struct.__st_parameter_dt* %dt_parm.15, i32 0, i32 0
%178 = getelementptr inbounds %struct.__st_parameter_common* %177, i32 0, i32 2
store i8* getelementptr inbounds ([11 x i8]* @.cst, i64 0, i64 0), i8** %178, align 8
%179 = getelementptr inbounds %struct.__st_parameter_dt* %dt_parm.15, i32 0, i32 0
%180 = getelementptr inbounds %struct.__st_parameter_common* %179, i32 0, i32 3
store i32 27, i32* %180, align 4
%181 = getelementptr inbounds %struct.__st_parameter_dt* %dt_parm.15, i32 0, i32 0
%182 = getelementptr inbounds %struct.__st_parameter_common* %181, i32 0, i32 0
store i32 128, i32* %182, align 4
%183 = getelementptr inbounds %struct.__st_parameter_dt* %dt_parm.15, i32 0, i32 0
%184 = getelementptr inbounds %struct.__st_parameter_common* %183, i32 0, i32 1
store i32 6, i32* %184, align 4
call void @_gfortran_st_write(%struct.__st_parameter_dt* %dt_parm.15) nounwind
br label %“12”

“12”: ; preds = %“16”, %“11”
%185 = phi float [ %190, %“16” ], [ 0.000000e+00, %“11” ]
%186 = phi i64 [ %199, %“16” ], [ 1, %“11” ]
%187 = icmp sgt i64 %186, %89
br i1 %187, label %“17”, label %“13”

“13”: ; preds = %“12”
%188 = mul i64 %186, %85
%189 = add i64 %188, %not2
br label %“14”

“14”: ; preds = %“15”, %“13”
%190 = phi float [ %197, %“15” ], [ %185, %“13” ]
%191 = phi i64 [ %198, %“15” ], [ 1, %“13” ]
%192 = icmp sgt i64 %191, %83
br i1 %192, label %“16”, label %“15”

“15”: ; preds = %“14”
%193 = add i64 %191, %189
%194 = bitcast [0 x float]* %100 to float*
%195 = getelementptr float* %194, i64 %193
%196 = load float* %195, align 4
%197 = fadd float %196, %190
%198 = add i64 %191, 1
br label %“14”

“16”: ; preds = %“14”
%199 = add i64 %186, 1
br label %“12”

“17”: ; preds = %“12”
store float %185, float* %D.1604, align 4
call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32))(%struct.__st_parameter_dt %dt_parm.15, float* %D.1604, i32 4) nounwind
br label %“18”

“18”: ; preds = %“27”, %“17”
%200 = phi float [ %207, %“27” ], [ 0xFFF0000000000000, %“17” ]
%201 = phi i1 [ %208, %“27” ], [ false, %“17” ]
%202 = phi i1 [ %209, %“27” ], [ false, %“17” ]
%203 = phi i64 [ %237, %“27” ], [ 1, %“17” ]
%204 = icmp sgt i64 %203, %89
br i1 %204, label %“28”, label %“19”

“19”: ; preds = %“18”
%205 = mul i64 %203, %85
%206 = add i64 %205, %not2
br label %“20”

“20”: ; preds = %“26”, %“19”
%207 = phi float [ %233, %“26” ], [ %200, %“19” ]
%208 = phi i1 [ %234, %“26” ], [ %201, %“19” ]
%209 = phi i1 [ %235, %“26” ], [ %202, %“19” ]
%210 = phi i64 [ %236, %“26” ], [ 1, %“19” ]
%211 = icmp sgt i64 %210, %83
br i1 %211, label %“27”, label %“21”

“21”: ; preds = %“20”
%212 = icmp ne i1 %209, false
br i1 %212, label %“22”, label %“24”

“22”: ; preds = %“21”
%213 = add i64 %210, %206
%214 = bitcast [0 x float]* %100 to float*
%215 = getelementptr float* %214, i64 %213
%216 = load float* %215, align 4
%217 = fcmp ogt float %216, %207
%218 = icmp ne i1 %217, false
br i1 %218, label %“23”, label %“26”

“23”: ; preds = %“22”
%219 = add i64 %210, %206
%220 = bitcast [0 x float]* %100 to float*
%221 = getelementptr float* %220, i64 %219
%222 = load float* %221, align 4
br label %“26”

“24”: ; preds = %“21”
%223 = add i64 %210, %206
%224 = bitcast [0 x float]* %100 to float*
%225 = getelementptr float* %224, i64 %223
%226 = load float* %225, align 4
%227 = fcmp oge float %226, %207
%228 = icmp ne i1 %227, false
br i1 %228, label %“25”, label %“26”

“25”: ; preds = %“24”
%229 = add i64 %210, %206
%230 = bitcast [0 x float]* %100 to float*
%231 = getelementptr float* %230, i64 %229
%232 = load float* %231, align 4
br label %“26”

“26”: ; preds = %“25”, %“24”, %“23”, %“22”
%233 = phi float [ %232, %“25” ], [ %207, %“24” ], [ %222, %“23” ], [ %207, %“22” ]
%234 = phi i1 [ true, %“25” ], [ true, %“24” ], [ %208, %“23” ], [ %208, %“22” ]
%235 = phi i1 [ true, %“25” ], [ %209, %“24” ], [ %209, %“23” ], [ %209, %“22” ]
%236 = add i64 %210, 1
br label %“20”

“27”: ; preds = %“20”
%237 = add i64 %203, 1
br label %“18”

“28”: ; preds = %“18”
%238 = icmp ne i1 %202, false
br i1 %238, label %“33”, label %“29”

“29”: ; preds = %“28”
%239 = icmp ne i1 %201, false
br i1 %239, label %“30”, label %“31”

“30”: ; preds = %“29”
br label %“32”

“31”: ; preds = %“29”
br label %“32”

“32”: ; preds = %“31”, %“30”
%240 = phi float [ 0xC7EFFFFFE0000000, %“31” ], [ 0x7FF8000000000000, %“30” ]
br label %“33”

“33”: ; preds = %“32”, %“28”
%241 = phi float [ %240, %“32” ], [ %200, %“28” ]
store float %241, float* %D.1616, align 4
call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32))(%struct.__st_parameter_dt %dt_parm.15, float* %D.1616, i32 4) nounwind
br label %“34”

“34”: ; preds = %“43”, %“33”
%242 = phi float [ %249, %“43” ], [ 0x7FF0000000000000, %“33” ]
%243 = phi i1 [ %250, %“43” ], [ false, %“33” ]
%244 = phi i1 [ %251, %“43” ], [ false, %“33” ]
%245 = phi i64 [ %279, %“43” ], [ 1, %“33” ]
%246 = icmp sgt i64 %245, %89
br i1 %246, label %“44”, label %“35”

“35”: ; preds = %“34”
%247 = mul i64 %245, %85
%248 = add i64 %247, %not2
br label %“36”

“36”: ; preds = %“42”, %“35”
%249 = phi float [ %275, %“42” ], [ %242, %“35” ]
%250 = phi i1 [ %276, %“42” ], [ %243, %“35” ]
%251 = phi i1 [ %277, %“42” ], [ %244, %“35” ]
%252 = phi i64 [ %278, %“42” ], [ 1, %“35” ]
%253 = icmp sgt i64 %252, %83
br i1 %253, label %“43”, label %“37”

“37”: ; preds = %“36”
%254 = icmp ne i1 %251, false
br i1 %254, label %“38”, label %“40”

“38”: ; preds = %“37”
%255 = add i64 %252, %248
%256 = bitcast [0 x float]* %100 to float*
%257 = getelementptr float* %256, i64 %255
%258 = load float* %257, align 4
%259 = fcmp olt float %258, %249
%260 = icmp ne i1 %259, false
br i1 %260, label %“39”, label %“42”

“39”: ; preds = %“38”
%261 = add i64 %252, %248
%262 = bitcast [0 x float]* %100 to float*
%263 = getelementptr float* %262, i64 %261
%264 = load float* %263, align 4
br label %“42”

“40”: ; preds = %“37”
%265 = add i64 %252, %248
%266 = bitcast [0 x float]* %100 to float*
%267 = getelementptr float* %266, i64 %265
%268 = load float* %267, align 4
%269 = fcmp ole float %268, %249
%270 = icmp ne i1 %269, false
br i1 %270, label %“41”, label %“42”

“41”: ; preds = %“40”
%271 = add i64 %252, %248
%272 = bitcast [0 x float]* %100 to float*
%273 = getelementptr float* %272, i64 %271
%274 = load float* %273, align 4
br label %“42”

“42”: ; preds = %“41”, %“40”, %“39”, %“38”
%275 = phi float [ %274, %“41” ], [ %249, %“40” ], [ %264, %“39” ], [ %249, %“38” ]
%276 = phi i1 [ true, %“41” ], [ true, %“40” ], [ %250, %“39” ], [ %250, %“38” ]
%277 = phi i1 [ true, %“41” ], [ %251, %“40” ], [ %251, %“39” ], [ %251, %“38” ]
%278 = add i64 %252, 1
br label %“36”

“43”: ; preds = %“36”
%279 = add i64 %245, 1
br label %“34”

“44”: ; preds = %“34”
%280 = icmp ne i1 %244, false
br i1 %280, label %“49”, label %“45”

“45”: ; preds = %“44”
%281 = icmp ne i1 %243, false
br i1 %281, label %“46”, label %“47”

“46”: ; preds = %“45”
br label %“48”

“47”: ; preds = %“45”
br label %“48”

“48”: ; preds = %“47”, %“46”
%282 = phi float [ 0x47EFFFFFE0000000, %“47” ], [ 0x7FF8000000000000, %“46” ]
br label %“49”

“49”: ; preds = %“48”, %“44”
%283 = phi float [ %282, %“48” ], [ %242, %“44” ]
store float %283, float* %D.1628, align 4
call void bitcast (void (%struct.__st_parameter_dt*, i8*, i32)* @_gfortran_transfer_real_write to void (%struct.__st_parameter_dt*, float*, i32))(%struct.__st_parameter_dt %dt_parm.15, float* %D.1628, i32 4) nounwind
call void @_gfortran_st_write_done(%struct.__st_parameter_dt* %dt_parm.15) nounwind
call void bitcast (void (…)* @_gfortran_flush_i4 to void (i8*))(i8 null) nounwind
%284 = bitcast [0 x float]* %100 to i8*
%285 = icmp ne i8* %284, null
br i1 %285, label %“50”, label %“51”

“50”: ; preds = %“49”
call void @free(i8* %284) nounwind
br label %“51”

“51”: ; preds = %“50”, %“49”
%286 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 2
%287 = load [0 x float]** %286, align 8
%288 = bitcast [0 x float]* %287 to i8*
%289 = icmp ne i8* %288, null
br i1 %289, label %“52”, label %“53”

“52”: ; preds = %“51”
call void @free(i8* %288) nounwind
br label %“53”

“53”: ; preds = %“52”, %“51”
%290 = getelementptr inbounds %struct.FRAME.matmul* %FRAME.40, i32 0, i32 8
%291 = load [0 x float]** %290, align 8
%292 = bitcast [0 x float]* %291 to i8*
%293 = icmp ne i8* %292, null
br i1 %293, label %“54”, label %“55”

“54”: ; preds = %“53”
call void @free(i8* %292) nounwind
br label %“55”

“55”: ; preds = %“54”, %“53”
br label %return

return: ; preds = %“55”
ret void
}

declare noalias i8* @malloc(i64) nounwind

declare void @_gfortran_cpu_time_4(…)

declare void @_gfortran_st_write(%struct.__st_parameter_dt*)

declare void @_gfortran_transfer_real_write(%struct.__st_parameter_dt*, i8*, i32)

declare void @_gfortran_st_write_done(%struct.__st_parameter_dt*)

declare void @_gfortran_flush_i4(…)

declare void @free(i8*) nounwind

According to comment in tree-nested.c, these frames should be only introduced in case of debug or OpenMP lowering:

/* A subroutine of convert_nonlocal_reference_op. Create a local variable
in the nested function with DECL_VALUE_EXPR set to reference the true
variable in the parent function. This is used both for debug info
and in OpenMP lowering. */

However, in this code example we don’t have neither debugging, nor OpenMP.

How do you think, is it possible to disable those FRAME-s? Important for accurate CLooG/Polly handling.

  • D.

2012/7/31 Dmitry N. Mikushin <maemarcus@gmail.com>

According to comment in tree-nested.c, these frames should be only
introduced in case of debug or OpenMP lowering:

in case of *debug*. What if you pass -O1 / -O2 / -Owhatever ?

Hi Anton,

Still there, even with opts. I consulted with GCC guys and debugged f951 a little bit. The conclusion is that unfortunately this logic is always effective for nested calls using parent’s data (through the GCC function called convert_nonlocal_reference_op). Consider the provided test case: it has one func embedded into another one, and data of parent is used in nested without being passed in arguments. In this case as I understand FRAME is always created. Still, our question is if it is good to keep it for LLVM. This thing introduces additional unexpected load/stores and phi-nodes.

  • D.

2012/7/31 Anton Korobeynikov <anton@korobeynikov.info>

Hi Dmitry,

A DragonEgg/GCC-related question: do you know where these strange FRAME tokens
originate from (e.g. %struct.FRAME.matmul)?

these are produced by GCC's nested function lowering code. They represent the
variables on the parent function's stack. In your example the nested function
init_array is accessing the variables nx, ny, nz, A and B from the parent
function matmul.

Ciao, Duncan.

  Compiling simple Fortran code with