# 7.2 处理逻辑

在编译器主函数中，处理无效代码的代码片段如下：

```go
// file: cmd/compile/internal/gc/main.go

func Main() {
    // 忽略之前代码

    // 清除无效代码
    for _, n := range typecheck.Target.Decls {
        if n.Op() == ir.ODCLFUNC {
            deadcode.Func(n.(*ir.Func))
        }
    }

    // 忽略之后代码
}
```

对于所有的函数（包括方法），编译器将通过函数 `deadcode.Func()` 清除其无效代码。所有清除无效代码的逻辑都定义在文件 `cmd/compile/internal/deadcode/deadcode.go` 中，该文件总共只有100多行，逻辑相对简单。总体思路是遍历函数的语法树（IR Tree），然后对分支（Branch）及逻辑运算表达式进行判定，如果确实有可以清除掉的无效代码，则直接修改语法树。

我们先看一下其对 `if` 语句的处理：

```go
if n.Op() == ir.OIF {
    n := n.(*ir.IfStmt)
    n.Cond = expr(n.Cond)
    if ir.IsConst(n.Cond, constant.Bool) {
        var body ir.Nodes
        if ir.BoolVal(n.Cond) {
            n.Else = ir.Nodes{}
            body = n.Body
        } else {
            n.Body = ir.Nodes{}
            body = n.Else
        }
    }
}
```

如果 `if` 的条件语句的值是常量，则根据常量值在 `Body` 与 `Else` 中二选一。逻辑运算符的 `&&` 与 `||` 的处理逻辑如下：

```go
func expr(n ir.Node) ir.Node {
    // Perform dead-code elimination on short-circuited boolean
    // expressions involving constants with the intent of
    // producing a constant 'if' condition.
    switch n.Op() {
    case ir.OANDAND:
        n := n.(*ir.LogicalExpr)
        n.X = expr(n.X)
        n.Y = expr(n.Y)
        if ir.IsConst(n.X, constant.Bool) {
            if ir.BoolVal(n.X) {
                return n.Y // true && x => x
            } else {
                return n.X // false && x => false
            }
        }
    case ir.OOROR:
        n := n.(*ir.LogicalExpr)
        n.X = expr(n.X)
        n.Y = expr(n.Y)
        if ir.IsConst(n.X, constant.Bool) {
            if ir.BoolVal(n.X) {
                return n.X // true || x => true
            } else {
                return n.Y // false || x => x
            }
        }
    }
    return n
}
```

如果第一个分量是常量，那么编译器会根据常量值从两个分量中二选一，用来替换掉之前的整个逻辑表达式。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gocompiler.shizhz.me/7.-golang-bian-yi-qi-qing-chu-wu-xiao-dai-ma/7.2-chu-li-luo-ji.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
