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