了解IR流程

时间:2018-05-31 13:48:11

标签: llvm llvm-clang llvm-ir

我发现很难理解LLVM的IR流程。这项工作背后的动机是将给定的c / c ++程序转换为它的SSA表示。 我发现https://releases.llvm.org/3.4.2/docs/tutorial/LangImpl7.html,我们可以通过使用-mem2reg传递从LLVM的IR获得SSA。 作为一个初学者,我发现很难理解IR的流程,虽然我无法理解至少使用的一些不同类型的指令,如load,store,icmp.fcmp,br label,br i1等。 但是,块发生的顺序让我很困惑。如果有任何材料可以帮助我理解流程会有所帮助。

我看到llvm还使用opt选项" -view-cfg"提供了一个可视化表示的界面。并使用" dot -Tpdf cfg_file.dot -o cfg.pdf"。虽然它有很多帮助,但有流量连接,我无法理解它。

现在我的主要问题是我无法理解最后五个街区。这些(最后五个)块的顺序和控制流程是什么?目标是使用LLVM的IR表示创建程序的SSA(单个静态分配)。 请在下面找到IR和C程序的源代码。还可以找到指向我的Google驱动器CFG文件的链接。

  

LLVM的IR

    call void @llvm.dbg.value(metadata %struct.INPUT_VAL* %input, metadata !31, metadata !DIExpression()), !dbg !42

    call void @llvm.dbg.value(metadata %struct.RETURN_VAL* %ret_val, metadata !32, metadata !DIExpression()), !dbg !43

    call void @llvm.dbg.value(metadata i32 2, metadata !33, metadata !DIExpression()), !dbg !44

    call void @llvm.dbg.value(metadata double 7.000000e+01, metadata !36, metadata !DIExpression()), !dbg !45

    call void @llvm.dbg.value(metadata double 6.600000e+01, metadata !37, metadata !DIExpression()), !dbg !46

    %temperature = getelementptr inbounds %struct.INPUT_VAL, %struct.INPUT_VAL* %input, i64 0, i32 0, !dbg !47
    %tmp = load double, double* %temperature, align 8, !dbg !47, !tbaa !48
    call void @llvm.dbg.value(metadata double %tmp, metadata !35, metadata !DIExpression()), !dbg !53
    %cmp = fcmp oge double %tmp, 6.600000e+01, !dbg !54
    %cmp1 = fcmp olt double %tmp, 7.000000e+01, !dbg !56
    %or.cond49 = and i1 %cmp, %cmp1, !dbg !57
    br i1 %or.cond49, label %if.end9, label %if.else, !dbg !57

    %cmp2 = fcmp ult double %tmp, 7.000000e+01, !dbg !58
    br i1 %cmp2, label %if.else4, label %if.end9, !dbg !60

    %cmp5 = fcmp olt double %tmp, 6.600000e+01, !dbg !61
    %. = zext i1 %cmp5 to i32, !dbg !63
    br label %if.end9, !dbg !63

    %.pr52 = phi i32 [ 2, %entry ], [ 0, %if.else ], [ %., %if.else4 ]
    %tmp1 = load i32, i32* @thermostat.off_counter, align 4, !dbg !64, !tbaa !66
    %cmp10 = icmp sgt i32 %tmp1, 4, !dbg !68
    %tmp2 = load i32, i32* @thermostat.on_counter, align 4, !dbg !69
    %cmp11 = icmp sgt i32 %tmp2, 4, !dbg !70
    %or.cond = or i1 %cmp10, %cmp11, !dbg !71
    br i1 %or.cond, label %if.then12, label %if.end9.if.end13_crit_edge, !dbg !71

    %.pr.pre = load i32, i32* @thermostat.chatter_detect, align 4, !dbg !72, !tbaa !66
    br label %if.end13, !dbg !71

    store i32 0, i32* @thermostat.chatter_detect, align 4, !dbg !74, !tbaa !66
    br label %if.end13, !dbg !75

    %.pr = phi i32 [ %.pr.pre, %if.end9.if.end13_crit_edge ], [ 0, %if.then12 ], !dbg !72
    %cmp14 = icmp eq i32 %.pr52, 0, !dbg !76
    br i1 %cmp14, label %if.end16, label %if.then15, !dbg !77

    %inc = add nsw i32 %.pr, 1, !dbg !78
    store i32 %inc, i32* @thermostat.chatter_detect, align 4, !dbg !78, !tbaa !66
    br label %if.end16, !dbg !79

    %tmp3 = phi i32 [ %inc, %if.then15 ], [ %.pr, %if.end13 ], !dbg !80
    %cmp17 = icmp sgt i32 %tmp3, 2, !dbg !82
    %brmerge = or i1 %cmp17, %cmp14, !dbg !83
    br i1 %brmerge, label %if.end25.thread, label %if.end25, !dbg !83

    store i32 0, i32* @thermostat.on_counter, align 4, !dbg !84, !tbaa !66
    %inc22 = add nsw i32 %tmp1, 1, !dbg !87
    store i32 %inc22, i32* @thermostat.off_counter, align 4, !dbg !88, !tbaa !66
    br label %.thread, !dbg !89

    %inc24 = add nsw i32 %tmp2, 1, !dbg !90
    store i32 %inc24, i32* @thermostat.on_counter, align 4, !dbg !90, !tbaa !66
    store i32 0, i32* @thermostat.off_counter, align 4, !dbg !88, !tbaa !66
    %switch.selectcmp = icmp eq i32 %.pr52, 1, !dbg !89
    br i1 %switch.selectcmp, label %.thread, label %bb, !dbg !89

    %.ph56 = phi double [ 2.000000e+01, %if.end25.thread ], [ 1.000000e+02, %if.end25 ]
    br label %bb, !dbg !89

    %tmp4 = phi double [ %.ph56, %.thread ], [ 7.000000e+01, %if.end25 ]
    call void @llvm.dbg.value(metadata double %tmp4, metadata !34, metadata !DIExpression()), !dbg !92
    %u37 = getelementptr inbounds %struct.RETURN_VAL, %struct.RETURN_VAL* %ret_val, i64 0, i32 0, !dbg !93
    store double %tmp4, double* %u37, align 8, !dbg !94, !tbaa !48
    ret %struct.RETURN_VAL* %ret_val, !dbg !95

C计划

    #include "thermostat.h"  //contains structure information

    #ifdef DEBUG
      #include<stdio.h>
    #endif

    RETURN_VAL* thermostat(INPUT_VAL* input, RETURN_VAL* ret_val)
    {
        static int chatter_detect;
        static int previous_command_to_heater;
        static int on_counter, off_counter;
        static int command_to_heater;
        int chatter_limit=2;
        double u, room_temp;
        double MAX_TEMP=70.0, MED_TEMP=66.0;

    //  int NO_HEAT=0, NORMAL_HEAT = 2, FAST_HEAT = 1;

     room_temp = input->temperature;

        if(room_temp >= MED_TEMP && room_temp < MAX_TEMP)
            command_to_heater = 2;
        else if(room_temp >= MAX_TEMP)
            command_to_heater = 0;
        else if(room_temp < MED_TEMP)
            command_to_heater = 1;
        else
            command_to_heater = previous_command_to_heater;

        if(off_counter >= 5 || on_counter >= 5)
            chatter_detect = 0;

        if(command_to_heater != previous_command_to_heater)
            chatter_detect++;

        if(chatter_detect > chatter_limit)
            command_to_heater = previous_command_to_heater;

        if(command_to_heater == 0) {
            on_counter = 0;
            off_counter++;
        } else {
            on_counter++;
            off_counter = 0;
        }

        if (command_to_heater==0) 
            u = 20;
        else if (command_to_heater==1) 
            u = 100;
        else if (command_to_heater==2) 
            u = 70;
        ret_val->u = u;
      return ret_val;
    }

指向此IR https://drive.google.com/open?id=1wIvXR5PosWWViM4fo_jEaLpXkCbhYGSE

生成的CFG文件的链接

这方面的任何帮助或指针都会很棒。 谢谢,抱歉让问题变得复杂而冗长。如果有任何遗漏信息,请随时澄清。

0 个答案:

没有答案