• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { AbstractExpr, AbstractInvokeExpr, ArkConditionExpr } from '../base/Expr';
17import { AbstractRef } from '../base/Ref';
18import { ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, ArkReturnStmt, ArkThrowStmt, Stmt } from '../base/Stmt';
19import { Value } from '../base/Value';
20import { ExprUseReplacer } from './ExprUseReplacer';
21import { RefUseReplacer } from './RefUseReplacer';
22import { IRUtils } from './IRUtils';
23
24/**
25 * Replace old use(Value) of a Stmt inplace
26 */
27export class StmtUseReplacer {
28    private oldUse: Value;
29    private newUse: Value;
30
31    constructor(oldUse: Value, newUse: Value) {
32        this.oldUse = oldUse;
33        this.newUse = newUse;
34    }
35
36    public caseStmt(stmt: Stmt): void {
37        if (stmt instanceof ArkAssignStmt) {
38            this.caseAssignStmt(stmt);
39        } else if (stmt instanceof ArkInvokeStmt) {
40            this.caseInvokeStmt(stmt);
41        } else if (stmt instanceof ArkReturnStmt) {
42            this.caseReturnStmt(stmt);
43        } else if (stmt instanceof ArkIfStmt) {
44            this.caseIfStmt(stmt);
45        } else if (stmt instanceof ArkThrowStmt) {
46            this.caseThrowStmt(stmt);
47        }
48    }
49
50    private caseAssignStmt(stmt: ArkAssignStmt): void {
51        const lValue = stmt.getLeftOp();
52        if (lValue instanceof AbstractRef) {
53            const refUseReplacer = new RefUseReplacer(this.oldUse, this.newUse);
54            refUseReplacer.caseRef(lValue);
55        }
56
57        const rValue = stmt.getRightOp();
58        if (rValue === this.oldUse) {
59            IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse);
60            stmt.setRightOp(this.newUse);
61        } else if (rValue instanceof AbstractRef) {
62            const refUseReplacer = new RefUseReplacer(this.oldUse, this.newUse);
63            refUseReplacer.caseRef(rValue);
64        } else if (rValue instanceof AbstractExpr) {
65            const exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse);
66            exprUseReplacer.caseExpr(rValue);
67        }
68    }
69
70    private caseInvokeStmt(stmt: ArkInvokeStmt): void {
71        const invokeExpr = stmt.getInvokeExpr();
72        if (invokeExpr === this.oldUse) {
73            if (this.newUse instanceof AbstractInvokeExpr) {
74                IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse);
75                stmt.replaceInvokeExpr(this.newUse);
76            }
77        } else {
78            let exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse);
79            exprUseReplacer.caseExpr(stmt.getInvokeExpr());
80        }
81    }
82
83    private caseReturnStmt(stmt: ArkReturnStmt): void {
84        if (stmt.getOp() === this.oldUse) {
85            IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse);
86            stmt.setReturnValue(this.newUse);
87        }
88    }
89
90    private caseIfStmt(stmt: ArkIfStmt): void {
91        const conditionExpr = stmt.getConditionExpr();
92        if (conditionExpr === this.oldUse) {
93            if (this.newUse instanceof ArkConditionExpr) {
94                IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse);
95                stmt.setConditionExpr(this.newUse);
96            }
97        } else {
98            let exprUseReplacer = new ExprUseReplacer(this.oldUse, this.newUse);
99            exprUseReplacer.caseExpr(stmt.getConditionExpr());
100        }
101    }
102
103    private caseThrowStmt(stmt: ArkThrowStmt): void {
104        if (stmt.getOp() === this.oldUse) {
105            IRUtils.adjustOperandOriginalPositions(stmt, this.oldUse, this.newUse);
106            stmt.setOp(this.newUse);
107        }
108    }
109}
110