[llvm-dev] Is read and write variables always translated to load and store IR instructions?

Peng Yu via llvm-dev llvm-dev at lists.llvm.org
Sat Jan 19 09:09:40 PST 2019


Hi,

It seems that read and write access to variables are translated to
load and store IR instructions.

Are they only translated to load and store IR instructions in .ll
code? Could read and write accesses be translated to other IR
instructions (for .0.0.preopt.bc only)? Thanks.

$ clang -std=gnu99 -g3 -flto -Wall -pedantic -c -o main.o main.c
$ clang main.o -flto -fuse-ld=gold '-Wl,-plugin-opt=save-temps' -o main.exe
$ cat main.c
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

int i;

struct {
  int x;
  int y;
} a[10];

void print() {
  puts("Hello World!");
}

int main(int argc, char *argv[]) {
  ++i;
  if(i) {
    ++a[0].x;
    print();
    printf("%d\n", i);
    printf("%d\n", a[0].x);
  }
  return 0;
}
$ cat main.exe.0.0.preopt.ll
source_filename = "ld-temp.o"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

%struct.anon = type { i32, i32 }

@.str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1
@i = common dso_local global i32 0, align 4, !dbg !0
@a = common dso_local global [10 x %struct.anon] zeroinitializer,
align 16, !dbg !6
@.str.1 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @print() #0 !dbg !20 {
  %1 = call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x
i8]* @.str, i32 0, i32 0)), !dbg !23
  ret void, !dbg !24
}

declare i32 @puts(i8*) #1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main(i32, i8**) #0 !dbg !25 {
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  %5 = alloca i8**, align 8
  store i32 0, i32* %3, align 4
  store i32 %0, i32* %4, align 4
  call void @llvm.dbg.declare(metadata i32* %4, metadata !31, metadata
!DIExpression()), !dbg !32
  store i8** %1, i8*** %5, align 8
  call void @llvm.dbg.declare(metadata i8*** %5, metadata !33,
metadata !DIExpression()), !dbg !34
  %6 = load i32, i32* @i, align 4, !dbg !35
  %7 = add nsw i32 %6, 1, !dbg !35
  store i32 %7, i32* @i, align 4, !dbg !35
  %8 = load i32, i32* @i, align 4, !dbg !36
  %9 = icmp ne i32 %8, 0, !dbg !36
  br i1 %9, label %10, label %17, !dbg !38

; <label>:10:                                     ; preds = %2
  %11 = load i32, i32* getelementptr inbounds ([10 x %struct.anon],
[10 x %struct.anon]* @a, i64 0, i64 0, i32 0), align 16, !dbg !39
  %12 = add nsw i32 %11, 1, !dbg !39
  store i32 %12, i32* getelementptr inbounds ([10 x %struct.anon], [10
x %struct.anon]* @a, i64 0, i64 0, i32 0), align 16, !dbg !39
  call void @print(), !dbg !41
  %13 = load i32, i32* @i, align 4, !dbg !42
  %14 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 %13), !dbg !43
  %15 = load i32, i32* getelementptr inbounds ([10 x %struct.anon],
[10 x %struct.anon]* @a, i64 0, i64 0, i32 0), align 16, !dbg !44
  %16 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x
i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 %15), !dbg !45
  br label %17, !dbg !46

; <label>:17:                                     ; preds = %10, %2
  ret i32 0, !dbg !47
}

; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.declare(metadata, metadata, metadata) #2

declare i32 @printf(i8*, ...) #1

attributes #0 = { noinline nounwind optnone uwtable
"correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-jump-tables"="false"
"no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false"
"no-trapping-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false"
"disable-tail-calls"="false" "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false" "no-nans-fp-math"="false"
"no-signed-zeros-fp-math"="false" "no-trapping-math"="false"
"stack-protector-buffer-size"="8" "target-cpu"="x86-64"
"target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind readnone speculatable }

!llvm.dbg.cu = !{!2}
!llvm.ident = !{!16}
!llvm.module.flags = !{!17, !18, !19}

!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "i", scope: !2, file: !3, line:
4, type: !12, isLocal: false, isDefinition: true)
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3,
producer: "clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)",
isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums:
!4, globals: !5)
!4 = !{}
!5 = !{!0, !6}
!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
!7 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line:
9, type: !8, isLocal: false, isDefinition: true)
!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 640,
elements: !14)
!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3,
line: 6, size: 64, elements: !10)
!10 = !{!11, !13}
!11 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !9, file:
!3, line: 7, baseType: !12, size: 32)
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: !9, file:
!3, line: 8, baseType: !12, size: 32, offset: 32)
!14 = !{!15}
!15 = !DISubrange(count: 10)
!16 = !{!"clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)"}
!17 = !{i32 2, !"Dwarf Version", i32 4}
!18 = !{i32 2, !"Debug Info Version", i32 3}
!19 = !{i32 1, !"wchar_size", i32 4}
!20 = distinct !DISubprogram(name: "print", scope: !3, file: !3, line:
11, type: !21, isLocal: false, isDefinition: true, scopeLine: 11,
isOptimized: false, unit: !2, retainedNodes: !4)
!21 = !DISubroutineType(types: !22)
!22 = !{null}
!23 = !DILocation(line: 12, column: 3, scope: !20)
!24 = !DILocation(line: 13, column: 1, scope: !20)
!25 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line:
15, type: !26, isLocal: false, isDefinition: true, scopeLine: 15,
flags: DIFlagPrototyped, isOptimized: false, unit: !2, retainedNodes:
!4)
!26 = !DISubroutineType(types: !27)
!27 = !{!12, !12, !28}
!28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 64)
!29 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !30, size: 64)
!30 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
!31 = !DILocalVariable(name: "argc", arg: 1, scope: !25, file: !3,
line: 15, type: !12)
!32 = !DILocation(line: 15, column: 14, scope: !25)
!33 = !DILocalVariable(name: "argv", arg: 2, scope: !25, file: !3,
line: 15, type: !28)
!34 = !DILocation(line: 15, column: 26, scope: !25)
!35 = !DILocation(line: 16, column: 3, scope: !25)
!36 = !DILocation(line: 17, column: 6, scope: !37)
!37 = distinct !DILexicalBlock(scope: !25, file: !3, line: 17, column: 6)
!38 = !DILocation(line: 17, column: 6, scope: !25)
!39 = !DILocation(line: 18, column: 5, scope: !40)
!40 = distinct !DILexicalBlock(scope: !37, file: !3, line: 17, column: 9)
!41 = !DILocation(line: 19, column: 5, scope: !40)
!42 = !DILocation(line: 20, column: 20, scope: !40)
!43 = !DILocation(line: 20, column: 5, scope: !40)
!44 = !DILocation(line: 21, column: 25, scope: !40)
!45 = !DILocation(line: 21, column: 5, scope: !40)
!46 = !DILocation(line: 22, column: 3, scope: !40)
!47 = !DILocation(line: 23, column: 3, scope: !25)

-- 
Regards,
Peng


More information about the llvm-dev mailing list