201250093 谭子悦

Overview

The major task of Lab 6 is to build LLVM IR for global variables and if-else statements in SysY.

Based on Lab 5, this lab is easy to figure out.

Challenges

Global Array Initialization

In Lab 5, my initializing of an array is implemented by storing each value to each of the array's elements. But then I found that this pattern will not work on global variables: global variables are defined outside of function scopes, and hence we can not add store statements for them.

Then I STFW and RTFM, and found that there is a kind of value called ConstArray, and we can use it to initialize a global array variable.

After solving this problem, I also refactored my code to let local array variables be initialized in a similar way: define an extra global array variable to store their initial values, and then assign this value to them with the LLVM instruction memcpy.

However, this causes another issue: if the initial value of a local array variable contains a non-constant, then we will use the local variable to initialize the global variable, which is an illegal behavior.

Therefore, I gave up this optimization and choose the traditional way.

<aside> 💡 How does Clang handle this?

Through my observation, I speculate that Clang will first detect whether the initialization contains any non-constant value and:

Conditional Branch

The LLVM instruction for the conditional branch is:

br i1 <cond>, label <iftrue>, label <iffalse>

It requires that both the target basic blocks for “then” and “else” be specified.

Then the problem comes: what if we do not need an “else” branch?

To find out the solution, I observe the code generated by Clang and found the solution to be really trivial: just make the “else” branch do nothing and jump.

So the CFGs under any circumstances will be like this:

Untitled

Separating Definition & Declaration

The last problem I met was the error prompt: