1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* -*- mode: C; c-basic-offset: 3; -*- */ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- begin ir_opt.c ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2004-2012 OpenWorks LLP 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.net 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02110-1301, USA. 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_basictypes.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_ir.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_util.h" 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "main_globals.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "ir_opt.h" 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set to 1 for lots of debugging output. */ 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEBUG_IROPT 0 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Set to 1 to gather some statistics. Currently only for sameIRExprs. */ 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define STATS_IROPT 0 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* What iropt does, 29 Dec 04. 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It takes an IRSB and produces a new one with the same meaning, 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown defined thus: 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown After execution of the new BB, all guest state and guest memory is 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the same as after execution of the original. This is true 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regardless of how the block was exited (at the end vs side exit). 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In addition, parts of the guest state will be identical to that 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown created by execution of the original at the following observation 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown points: 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * In a dirty helper call, any parts of the guest state that the 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown helper states that it reads or modifies will be up to date. 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Also, guest memory will be up to date. Parts of the guest state 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not marked as being read or modified by the helper cannot be 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumed to be up-to-date at the point where the helper is called. 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * If iropt_register_updates == VexRegUpdUnwindregsAtMemAccess : 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Immediately prior to any load or store, those parts of the guest 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state marked as requiring precise exceptions will be up to date. 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Also, guest memory will be up to date. Parts of the guest state 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not marked as requiring precise exceptions cannot be assumed to 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be up-to-date at the point of the load/store. 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng If iropt_register_updates == VexRegUpdAllregsAtMemAccess: 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Same as minimal, but all the guest state is up to date at memory 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng exception points. 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng If iropt_register_updates == VexRegUpdAllregsAtEachInsn : 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Guest state is up to date at each instruction. 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The relative order of loads and stores (including loads/stores of 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest memory done by dirty helpers annotated as such) is not 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown changed. However, the relative order of loads with no intervening 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stores/modifies may be changed. 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Transformation order 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~~~~~~~~~~~~~~~~~~~~ 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown There are three levels of optimisation, controlled by 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_control.iropt_level. Define first: 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Cheap transformations" are the following sequence: 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Redundant-Get removal 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Redundant-Put removal 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Constant propagation/folding 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Dead code removal 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Specialisation of clean helper functions 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Dead code removal 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Expensive transformations" are the following sequence: 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CSE 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Folding of add/sub chains 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Redundant-GetI removal 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Redundant-PutI removal 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Dead code removal 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Then the transformations are as follows, as defined by 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_control.iropt_level: 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Level 0: 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Flatten into atomic form. 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Level 1: the following sequence: 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Flatten into atomic form. 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Cheap transformations. 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Level 2: the following sequence 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Flatten into atomic form. 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Cheap transformations. 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If block contains any floating or vector types, CSE. 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If block contains GetI or PutI, Expensive transformations. 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Try unrolling loops. Three possible outcomes: 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - No effect: do nothing more. 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - Unrolled a loop, and block does not contain GetI or PutI: 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Do: * CSE 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Dead code removal 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - Unrolled a loop, and block contains GetI or PutI: 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Do: * Expensive transformations 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Cheap transformations 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Implementation notes, 29 Dec 04. 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TODO (important): I think rPutI removal ignores precise exceptions 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and is therefore in a sense, wrong. In the sense that PutIs are 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumed not to write parts of the guest state that we need to have 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown up-to-date at loads/stores. So far on x86 guest that has not 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mattered since indeed only the x87 FP registers and tags are 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown accessed using GetI/PutI, and there is no need so far for them to 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be up to date at mem exception points. The rPutI pass should be 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fixed. 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TODO: improve pessimistic handling of precise exceptions 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the tree builder. 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TODO: check interaction of rGetI and dirty helpers. 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown F64i constants are treated differently from other constants. 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown They are not regarded as atoms, and instead lifted off and 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bound to temps. This allows them to participate in CSE, which 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is important for getting good performance for x86 guest code. 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CSE up F64 literals (already doing F64is) 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CSE: consider carefully the requirement for precise exns 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prior to making CSE any more aggressive. */ 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Finite mappery, of a sort ---*/ 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* General map from HWord-sized thing HWord-sized thing. Could be by 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hashing, but it's not clear whether or not this would really be any 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown faster. */ 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool* inuse; 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord* key; 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord* val; 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int size; 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int used; 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW; 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HashHW* newHHW ( void ) 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* h = LibVEX_Alloc(sizeof(HashHW)); 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->size = 8; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->used = 0; 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->inuse = LibVEX_Alloc(h->size * sizeof(Bool)); 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->key = LibVEX_Alloc(h->size * sizeof(HWord)); 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->val = LibVEX_Alloc(h->size * sizeof(HWord)); 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return h; 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Look up key in the map. */ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool lookupHHW ( HashHW* h, /*OUT*/HWord* val, HWord key ) 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("lookupHHW(%llx)\n", key ); */ 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < h->used; i++) { 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (h->inuse[i] && h->key[i] == key) { 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (val) 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *val = h->val[i]; 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add key->val to the map. Replaces any existing binding for key. */ 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addToHHW ( HashHW* h, HWord key, HWord val ) 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j; 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("addToHHW(%llx, %llx)\n", key, val); */ 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Find and replace existing binding, if any. */ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < h->used; i++) { 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (h->inuse[i] && h->key[i] == key) { 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->val[i] = val; 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ensure a space is available. */ 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (h->used == h->size) { 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy into arrays twice the size. */ 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool* inuse2 = LibVEX_Alloc(2 * h->size * sizeof(Bool)); 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord* key2 = LibVEX_Alloc(2 * h->size * sizeof(HWord)); 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord* val2 = LibVEX_Alloc(2 * h->size * sizeof(HWord)); 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = j = 0; i < h->size; i++) { 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!h->inuse[i]) continue; 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inuse2[j] = True; 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key2[j] = h->key[i]; 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown val2[j] = h->val[i]; 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j++; 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->used = j; 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->size *= 2; 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->inuse = inuse2; 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->key = key2; 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->val = val2; 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Finally, add it. */ 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(h->used < h->size); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->inuse[h->used] = True; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->key[h->used] = key; 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->val[h->used] = val; 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->used++; 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Flattening out a BB into atomic SSA form ---*/ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Non-critical helper, heuristic for reducing the number of tmp-tmp 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown copies made by flattening. If in doubt return False. */ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool isFlat ( IRExpr* e ) 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Get) 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Binop) 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( isIRAtom(e->Iex.Binop.arg1) 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isIRAtom(e->Iex.Binop.arg2) ); 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Load) 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return isIRAtom(e->Iex.Load.addr); 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Flatten out 'ex' so it is atomic, returning a new expression with 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the same value, after having appended extra IRTemp assignments to 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the end of 'bb'. */ 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* flatten_Expr ( IRSB* bb, IRExpr* ex ) 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** newargs; 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRType ty = typeOfIRExpr(bb->tyenv, ex); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp t1; 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (ex->tag) { 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_GetI(ex->Iex.GetI.descr, 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.GetI.ix), 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.GetI.bias))); 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt_WrTmp(t1, ex)); 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Qop: { 302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRQop* qop = ex->Iex.Qop.details; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Qop(qop->op, 306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, qop->arg1), 307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, qop->arg2), 308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, qop->arg3), 309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, qop->arg4)))); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Triop: { 314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTriop* triop = ex->Iex.Triop.details; 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Triop(triop->op, 318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, triop->arg1), 319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, triop->arg2), 320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng flatten_Expr(bb, triop->arg3)))); 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Binop(ex->Iex.Binop.op, 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Binop.arg1), 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Binop.arg2)))); 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Unop(ex->Iex.Unop.op, 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Unop.arg)))); 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Load(ex->Iex.Load.end, 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.Load.ty, 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Load.addr)))); 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown newargs = shallowCopyIRExprVec(ex->Iex.CCall.args); 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; newargs[i]; i++) 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown newargs[i] = flatten_Expr(bb, newargs[i]); 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_CCall(ex->Iex.CCall.cee, 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.CCall.retty, 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown newargs))); 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Mux0X(flatten_Expr(bb, ex->Iex.Mux0X.cond), 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Mux0X.expr0), 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Expr(bb, ex->Iex.Mux0X.exprX)))); 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Lift F64i constants out onto temps so they can be CSEd 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown later. */ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ex->Iex.Const.con->tag == Ico_F64i) { 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t1 = newIRTemp(bb->tyenv, ty); 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(t1, 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Const(ex->Iex.Const.con))); 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_RdTmp(t1); 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Leave all other constants alone. */ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ex; 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ex; 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(ex); 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("flatten_Expr"); 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append a completely flattened form of 'st' to the end of 'bb'. */ 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void flatten_Stmt ( IRSB* bb, IRStmt* st ) 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr *e1, *e2, *e3, *e4, *e5; 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty *d, *d2; 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS *cas, *cas2; 399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti, *puti2; 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isIRAtom(st->Ist.Put.data)) { 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* optimisation to reduce the amount of heap wasted 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by the flattener */ 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* general case, always correct */ 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.Put.data); 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Put(st->Ist.Put.offset, e1)); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti = st->Ist.PutI.details; 414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e1 = flatten_Expr(bb, puti->ix); 415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = flatten_Expr(bb, puti->data); 416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti2 = mkIRPutI(puti->descr, e1, puti->bias, e2); 417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB(bb, IRStmt_PutI(puti2)); 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isFlat(st->Ist.WrTmp.data)) { 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* optimisation, to reduce the number of tmp-tmp 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown copies generated */ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* general case, always correct */ 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.WrTmp.data); 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_WrTmp(st->Ist.WrTmp.tmp, e1)); 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.Store.addr); 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = flatten_Expr(bb, st->Ist.Store.data); 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Store(st->Ist.Store.end, e1,e2)); 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, cas->addr); 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = cas->expdHi ? flatten_Expr(bb, cas->expdHi) : NULL; 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e3 = flatten_Expr(bb, cas->expdLo); 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e4 = cas->dataHi ? flatten_Expr(bb, cas->dataHi) : NULL; 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e5 = flatten_Expr(bb, cas->dataLo); 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas2 = mkIRCAS( cas->oldHi, cas->oldLo, cas->end, 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1, e2, e3, e4, e5 ); 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_CAS(cas2)); 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.LLSC.addr); 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = st->Ist.LLSC.storedata 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? flatten_Expr(bb, st->Ist.LLSC.storedata) 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : NULL; 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_LLSC(st->Ist.LLSC.end, 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.result, e1, e2)); 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2 = emptyIRDirty(); 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d2 = *d; 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->args = shallowCopyIRExprVec(d2->args); 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d2->mFx != Ifx_None) { 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->mAddr = flatten_Expr(bb, d2->mAddr); 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(d2->mAddr == NULL); 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->guard = flatten_Expr(bb, d2->guard); 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d2->args[i]; i++) 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->args[i] = flatten_Expr(bb, d2->args[i]); 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Dirty(d2)); 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, st); 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.AbiHint.base); 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = flatten_Expr(bb, st->Ist.AbiHint.nia); 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_AbiHint(e1, st->Ist.AbiHint.len, e2)); 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1 = flatten_Expr(bb, st->Ist.Exit.guard); 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb, IRStmt_Exit(e1, st->Ist.Exit.jk, 482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->Ist.Exit.dst, 483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->Ist.Exit.offsIP)); 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("flatten_Stmt"); 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRSB* flatten_BB ( IRSB* in ) 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* out; 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out = emptyIRSB(); 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->tyenv = deepCopyIRTypeEnv( in->tyenv ); 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < in->stmts_used; i++) 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (in->stmts[i]) 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown flatten_Stmt( out, in->stmts[i] ); 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->next = flatten_Expr( out, in->next ); 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->jumpkind = in->jumpkind; 505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng out->offsIP = in->offsIP; 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return out; 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- In-place removal of redundant GETs ---*/ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scan forwards, building up an environment binding (min offset, max 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown offset) pairs to values, which will either be temps or constants. 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing 't = Get(minoff,maxoff)', look up (minoff,maxoff) in the 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env and if it matches, replace the Get with the stored value. If 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there is no match, add a (minoff,maxoff) :-> t binding. 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing 'Put (minoff,maxoff) = t or c', first remove in the env 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any binding which fully or partially overlaps with (minoff,maxoff). 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Then add a new (minoff,maxoff) :-> t or c binding. */ 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Extract the min/max offsets from a guest state array descriptor. */ 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browninline 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void getArrayBounds ( IRRegArray* descr, 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt* minoff, UInt* maxoff ) 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *minoff = descr->base; 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *maxoff = *minoff + descr->nElems*sizeofIRType(descr->elemTy) - 1; 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((*minoff & ~0xFFFF) == 0); 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((*maxoff & ~0xFFFF) == 0); 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(*minoff <= *maxoff); 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create keys, of the form ((minoffset << 16) | maxoffset). */ 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt mk_key_GetPut ( Int offset, IRType ty ) 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* offset should fit in 16 bits. */ 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt minoff = offset; 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt maxoff = minoff + sizeofIRType(ty) - 1; 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((minoff & ~0xFFFF) == 0); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((maxoff & ~0xFFFF) == 0); 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (minoff << 16) | maxoff; 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt mk_key_GetIPutI ( IRRegArray* descr ) 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt minoff, maxoff; 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getArrayBounds( descr, &minoff, &maxoff ); 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((minoff & ~0xFFFF) == 0); 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert((maxoff & ~0xFFFF) == 0); 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (minoff << 16) | maxoff; 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Supposing h has keys of the form generated by mk_key_GetPut and 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mk_key_GetIPutI, invalidate any key which overlaps (k_lo 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .. k_hi). 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void invalidateOverlaps ( HashHW* h, UInt k_lo, UInt k_hi ) 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int j; 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt e_lo, e_hi; 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(k_lo <= k_hi); 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* invalidate any env entries which in any way overlap (k_lo 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .. k_hi) */ 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("invalidate %d .. %d\n", k_lo, k_hi ); */ 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < h->used; j++) { 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!h->inuse[j]) 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e_lo = (((UInt)h->key[j]) >> 16) & 0xFFFF; 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e_hi = ((UInt)h->key[j]) & 0xFFFF; 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e_lo <= e_hi); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e_hi < k_lo || k_hi < e_lo) 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; /* no overlap possible */ 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* overlap; invalidate */ 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown h->inuse[j] = False; 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void redundant_get_removal_BB ( IRSB* bb ) 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* env = newHHW(); 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt key = 0; /* keep gcc -O happy */ 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j; 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord val; 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st = bb->stmts[i]; 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with Gets */ 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.WrTmp.data->tag == Iex_Get) { 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* st is 't = Get(...)'. Look up in the environment and see 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if the Get can be replaced. */ 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* get = st->Ist.WrTmp.data; 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key = (HWord)mk_key_GetPut( get->Iex.Get.offset, 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get->Iex.Get.ty ); 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (lookupHHW(env, &val, (HWord)key)) { 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* found it */ 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note, we could do better here. If the types are 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown different we don't do the substitution, since doing so 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown could lead to invalidly-typed IR. An improvement would 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be to stick in a reinterpret-style cast, although that 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown would make maintaining flatness more difficult. */ 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* valE = (IRExpr*)val; 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool typesOK = toBool( typeOfIRExpr(bb->tyenv,valE) 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == st->Ist.WrTmp.data->Iex.Get.ty ); 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typesOK && DEBUG_IROPT) { 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("rGET: "); ppIRExpr(get); 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" -> "); ppIRExpr(valE); 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typesOK) 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_WrTmp(st->Ist.WrTmp.tmp, valE); 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Not found, but at least we know that t and the Get(...) 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are now associated. So add a binding to reflect that 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fact. */ 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToHHW( env, (HWord)key, 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HWord)(void*)(IRExpr_RdTmp(st->Ist.WrTmp.tmp)) ); 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with Puts: invalidate any env entries overlapped by this 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Put */ 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Put || st->tag == Ist_PutI) { 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt k_lo, k_hi; 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Put) { 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key = mk_key_GetPut( st->Ist.Put.offset, 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(st->tag == Ist_PutI); 643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng key = mk_key_GetIPutI( st->Ist.PutI.details->descr ); 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown k_lo = (key >> 16) & 0xFFFF; 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown k_hi = key & 0xFFFF; 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidateOverlaps(env, k_lo, k_hi); 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Dirty) { 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with dirty helpers which write or modify guest state. 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Invalidate the entire env. We could do a lot better 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown here. */ 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d = st->Ist.Dirty.details; 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool writes = False; 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < d->nFxState; j++) { 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->fxState[j].fx == Ifx_Modify 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || d->fxState[j].fx == Ifx_Write) 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown writes = True; 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (writes) { 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* dump the entire env (not clever, but correct ...) */ 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < env->used; j++) 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env->inuse[j] = False; 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) vex_printf("rGET: trash env due to dirty helper\n"); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* add this one to the env, if appropriate */ 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Put) { 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Put.data)); 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToHHW( env, (HWord)key, (HWord)(st->Ist.Put.data)); 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* for (i = 0; i < bb->stmts_used; i++) */ 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- In-place removal of redundant PUTs ---*/ 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find any Get uses in st and invalidate any partially or fully 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlapping ranges listed in env. Due to the flattening phase, the 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown only stmt kind we expect to find a Get on is IRStmt_WrTmp. */ 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handle_gets_Stmt ( 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* env, 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st, 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*preciseMemExnsFn)(Int,Int) 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int j; 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt key = 0; /* keep gcc -O happy */ 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isGet; 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool memRW = False; 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* e; 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is the only interesting case. Deal with Gets in the RHS 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expression. */ 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e = st->Ist.WrTmp.data; 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isGet = True; 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key = mk_key_GetPut ( e->Iex.Get.offset, e->Iex.Get.ty ); 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isGet = True; 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key = mk_key_GetIPutI ( e->Iex.GetI.descr ); 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isGet = False; 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memRW = True; 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isGet = False; 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isGet) { 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt k_lo, k_hi; 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown k_lo = (key >> 16) & 0xFFFF; 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown k_hi = key & 0xFFFF; 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidateOverlaps(env, k_lo, k_hi); 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Be very conservative for dirty helper calls; dump the entire 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown environment. The helper might read guest state, in which 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case it needs to be flushed first. Also, the helper might 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown access guest memory, in which case all parts of the guest 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state requiring precise exceptions needs to be flushed. The 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown crude solution is just to flush everything; we could easily 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enough do a lot better if needed. */ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Probably also overly-conservative, but also dump everything 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if we hit a memory bus event (fence, lock, unlock). Ditto 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AbiHints, CASs, LLs and SCs. */ 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.base)); 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.nia)); 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* fall through */ 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < env->used; j++) 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env->inuse[j] = False; 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* all other cases are boring. */ 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.addr)); 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.data)); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memRW = True; 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Exit.guard)); 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(st->Ist.PutI.details->ix)); 766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(st->Ist.PutI.details->data)); 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("handle_gets_Stmt"); 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (memRW) { 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This statement accesses memory. So we need to dump all parts 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of the environment corresponding to guest state that may not 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be reordered with respect to memory references. That means 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown at least the stack pointer. */ 785663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (vex_control.iropt_register_updates) { 786663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VexRegUpdAllregsAtMemAccess: 787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Precise exceptions required at mem access. 788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Flush all guest state. */ 789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (j = 0; j < env->used; j++) 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env->inuse[j] = False; 791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case VexRegUpdUnwindregsAtMemAccess: 793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (j = 0; j < env->used; j++) { 794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!env->inuse[j]) 795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng continue; 796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Just flush the minimal amount required, as computed by 797663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng preciseMemExnsFn. */ 798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord k_lo = (env->key[j] >> 16) & 0xFFFF; 799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng HWord k_hi = env->key[j] & 0xFFFF; 800663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (preciseMemExnsFn( k_lo, k_hi )) 801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env->inuse[j] = False; 802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // VexRegUpdAllregsAtEachInsn cannot happen here. 806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Neither any rubbish other value. 807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(0); 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* if (memRW) */ 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scan backwards, building up a set of (min offset, max 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown offset) pairs, indicating those parts of the guest state 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for which the next event is a write. 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing a conditional exit, empty the set. 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing 'Put (minoff,maxoff) = t or c', if (minoff,maxoff) is 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown completely within the set, remove the Put. Otherwise, add 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (minoff,maxoff) to the set. 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing 'Get (minoff,maxoff)', remove any part of the set 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlapping (minoff,maxoff). The same has to happen for any events 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which implicitly read parts of the guest state: dirty helper calls 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and loads/stores. 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void redundant_put_removal_BB ( 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb, 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*preciseMemExnsFn)(Int,Int) 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j; 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isPut; 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt key = 0; /* keep gcc -O happy */ 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert 841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess 842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess); 843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* env = newHHW(); 845663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Initialise the running env with the fact that the final exit 847663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng writes the IP (or, whatever it claims to write. We don't 848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng care.) */ 849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng key = mk_key_GetPut(bb->offsIP, typeOfIRExpr(bb->tyenv, bb->next)); 850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addToHHW(env, (HWord)key, 0); 851663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And now scan backwards through the statements. */ 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb->stmts_used-1; i >= 0; i--) { 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with conditional exits. */ 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Exit) { 861663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //Bool re_add; 862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Need to throw out from the env, any part of it which 863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng doesn't overlap with the guest state written by this exit. 864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Since the exit only writes one section, it's simplest to 865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do this: (1) check whether env contains a write that 866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng completely overlaps the write done by this exit; (2) empty 867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng out env; and (3) if (1) was true, add the write done by 868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng this exit. 869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng To make (1) a bit simpler, merely search for a write that 871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng exactly matches the one done by this exit. That's safe 872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng because it will fail as often or more often than a full 873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng overlap check, and failure to find an overlapping write in 874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env is the safe case (we just nuke env if that 875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng happens). */ 876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //vassert(isIRAtom(st->Ist.Exit.guard)); 877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* (1) */ 878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //key = mk_key_GetPut(st->Ist.Exit.offsIP, 879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // typeOfIRConst(st->Ist.Exit.dst)); 880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //re_add = lookupHHW(env, NULL, key); 881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* (2) */ 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < env->used; j++) 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env->inuse[j] = False; 884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* (3) */ 885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng //if (0 && re_add) 886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // addToHHW(env, (HWord)key, 0); 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with Puts */ 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isPut = True; 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key = mk_key_GetPut( st->Ist.Put.offset, 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Put.data)); 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isPut = True; 900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng key = mk_key_GetIPutI( st->Ist.PutI.details->descr ); 901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(st->Ist.PutI.details->ix)); 902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(st->Ist.PutI.details->data)); 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown isPut = False; 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isPut && st->tag != Ist_PutI) { 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* See if any single entry in env overlaps this Put. This is 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simplistic in that the transformation is valid if, say, two 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown or more entries in the env overlap this Put, but the use of 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lookupHHW will only find a single entry which exactly 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlaps this Put. This is suboptimal but safe. */ 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (lookupHHW(env, NULL, (HWord)key)) { 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This Put is redundant because a later one will overwrite 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it. So NULL (nop) it out. */ 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("rPUT: "); ppIRStmt(st); 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_NoOp(); 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We can't demonstrate that this Put is redundant, so add it 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to the running collection. */ 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToHHW(env, (HWord)key, 0); 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal with Gets. These remove bits of the environment since 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown appearance of a Get means that the next event for that slice 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of the guest state is no longer a write, but a read. Also 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deals with implicit reads of guest state needed to maintain 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown precise exceptions. */ 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handle_gets_Stmt( env, st, preciseMemExnsFn ); 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Constant propagation and folding ---*/ 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if STATS_IROPT 944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* How often sameIRExprs was invoked */ 945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt invocation_count; 946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* How often sameIRExprs recursed through IRTemp assignments */ 947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt recursion_count; 948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* How often sameIRExprs found identical IRExprs */ 949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt success_count; 950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* How often recursing through assignments to IRTemps helped 951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng establishing equality. */ 952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt recursion_success_count; 953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Whether or not recursing through an IRTemp assignment helped 954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng establishing IRExpr equality for a given sameIRExprs invocation. */ 955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool recursion_helped; 956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Whether or not a given sameIRExprs invocation recursed through an 957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTemp assignment */ 958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool recursed; 959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Maximum number of nodes ever visited when comparing two IRExprs. */ 960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt max_nodes_visited; 961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* STATS_IROPT */ 962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Count the number of nodes visited for a given sameIRExprs invocation. */ 964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UInt num_nodes_visited; 965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Do not visit more than NODE_LIMIT nodes when comparing two IRExprs. 967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This is to guard against performance degradation by visiting large 968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng trees without success. */ 969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define NODE_LIMIT 30 970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The env in this section is a map from IRTemp to IRExpr*, 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that is, an array indexed by IRTemp. */ 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Do both expressions compute the same value? The answer is generally 976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng conservative, i.e. it will report that the expressions do not compute 977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the same value when in fact they do. The reason is that we do not 978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng keep track of changes in the guest state and memory. Thusly, two 979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Get's, GetI's or Load's, even when accessing the same location, will be 980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng assumed to compute different values. After all the accesses may happen 981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng at different times and the guest state / memory can have changed in 982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the meantime. 983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng XXX IMPORTANT XXX the two expressions must have the same IR type. 985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO NOT CALL HERE WITH DIFFERENTLY-TYPED EXPRESSIONS. */ 986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* JRS 20-Mar-2012: split sameIRExprs_aux into a fast inlineable 988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng wrapper that deals with the common tags-don't-match case, and a 989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng slower out of line general case. Saves a few insns. */ 990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng__attribute__((noinline)) 992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool sameIRExprs_aux2 ( IRExpr** env, IRExpr* e1, IRExpr* e2 ); 993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenginline 995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool sameIRExprs_aux ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e1->tag != e2->tag) return False; 998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return sameIRExprs_aux2(env, e1, e2); 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng__attribute__((noinline)) 1002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool sameIRExprs_aux2 ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (num_nodes_visited++ > NODE_LIMIT) return False; 1005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e1->tag) { 1007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_RdTmp: 1008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e1->Iex.RdTmp.tmp == e2->Iex.RdTmp.tmp) return True; 1009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (env[e1->Iex.RdTmp.tmp] && env[e2->Iex.RdTmp.tmp]) { 1011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool same = sameIRExprs_aux(env, env[e1->Iex.RdTmp.tmp], 1012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng env[e2->Iex.RdTmp.tmp]); 1013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if STATS_IROPT 1014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng recursed = True; 1015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (same) recursion_helped = True; 1016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 1017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return same; 1018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 1020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Get: 1022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_GetI: 1023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Load: 1024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Guest state / memory could have changed in the meantime. */ 1025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 1026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Binop: 1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool( e1->Iex.Binop.op == e2->Iex.Binop.op 1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, e1->Iex.Binop.arg1, 1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Binop.arg1 ) 1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, e1->Iex.Binop.arg2, 1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Binop.arg2 )); 1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Unop: 1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool( e1->Iex.Unop.op == e2->Iex.Unop.op 1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, e1->Iex.Unop.arg, 1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Unop.arg )); 1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Const: { 1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *c1 = e1->Iex.Const.con; 1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *c2 = e2->Iex.Const.con; 1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(c1->tag == c2->tag); 1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (c1->tag) { 1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U1: return toBool( c1->Ico.U1 == c2->Ico.U1 ); 1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 ); 1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 ); 1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 ); 1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 ); 1049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: break; 1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 1052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Triop: { 1055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTriop *tri1 = e1->Iex.Triop.details; 1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTriop *tri2 = e2->Iex.Triop.details; 1057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool( tri1->op == tri2->op 1058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, tri1->arg1, tri2->arg1 ) 1059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, tri1->arg2, tri2->arg2 ) 1060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, tri1->arg3, tri2->arg3 )); 1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Mux0X: 1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool( sameIRExprs_aux( env, e1->Iex.Mux0X.cond, 1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Mux0X.cond ) 1066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, e1->Iex.Mux0X.expr0, 1067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Mux0X.expr0 ) 1068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs_aux( env, e1->Iex.Mux0X.exprX, 1069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2->Iex.Mux0X.exprX )); 1070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 1072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Not very likely to be "same". */ 1073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chenginline 1080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool sameIRExprs ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 1081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool same; 1083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng num_nodes_visited = 0; 1085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng same = sameIRExprs_aux(env, e1, e2); 1086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if STATS_IROPT 1088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ++invocation_count; 1089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (recursed) ++recursion_count; 1090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng success_count += same; 1091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (same && recursion_helped) 1092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ++recursion_success_count; 1093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (num_nodes_visited > max_nodes_visited) 1094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng max_nodes_visited = num_nodes_visited; 1095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng recursed = False; /* reset */ 1096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng recursion_helped = False; /* reset */ 1097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* STATS_IROPT */ 1098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return same; 1100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Debugging-only hack (not used in production runs): make a guess 1104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng whether sameIRExprs might assert due to the two args being of 1105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng different types. If in doubt return False. Is only used when 1106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng --vex-iropt-level > 0, that is, vex_control.iropt_verbosity > 0. 1107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bad because it duplicates functionality from typeOfIRExpr. See 1108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng comment on the single use point below for rationale. */ 1109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic 1110663860b1408516d02ebfcb3a9999a134e6cfb223Ben ChengBool debug_only_hack_sameIRExprs_might_assert ( IRExpr* e1, IRExpr* e2 ) 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e1->tag != e2->tag) return False; 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e1->tag) { 1114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Const: { 1115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* The only interesting case */ 1116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *c1 = e1->Iex.Const.con; 1117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRConst *c2 = e2->Iex.Const.con; 1118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return c1->tag != c2->tag; 1119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Is this literally IRExpr_Const(IRConst_U32(0)) ? */ 1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool isZeroU32 ( IRExpr* e ) 1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return toBool( e->tag == Iex_Const 1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && e->Iex.Const.con->tag == Ico_U32 1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && e->Iex.Const.con->Ico.U32 == 0); 1133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Is this literally IRExpr_Const(IRConst_U32(1---1)) ? */ 1136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool isOnesU32 ( IRExpr* e ) 1137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return toBool( e->tag == Iex_Const 1139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Const.con->tag == Ico_U32 1140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->Iex.Const.con->Ico.U32 == 0xFFFFFFFF ); 1141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Is this literally IRExpr_Const(IRConst_U64(0)) ? */ 1144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool isZeroU64 ( IRExpr* e ) 1145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return toBool( e->tag == Iex_Const 1147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && e->Iex.Const.con->tag == Ico_U64 1148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov && e->Iex.Const.con->Ico.U64 == 0); 1149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Is this an integer constant with value 0 ? */ 1152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool isZeroU ( IRExpr* e ) 1153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag != Iex_Const) return False; 1155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Const.con->tag) { 1156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U1: return toBool( e->Iex.Const.con->Ico.U1 == 0); 1157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U8: return toBool( e->Iex.Const.con->Ico.U8 == 0); 1158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U16: return toBool( e->Iex.Const.con->Ico.U16 == 0); 1159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U32: return toBool( e->Iex.Const.con->Ico.U32 == 0); 1160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U64: return toBool( e->Iex.Const.con->Ico.U64 == 0); 1161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: vpanic("isZeroU"); 1162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Is this an integer constant with value 1---1b ? */ 1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool isOnesU ( IRExpr* e ) 1167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag != Iex_Const) return False; 1169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Const.con->tag) { 1170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U8: return toBool( e->Iex.Const.con->Ico.U8 == 0xFF); 1171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U16: return toBool( e->Iex.Const.con->Ico.U16 == 0xFFFF); 1172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U32: return toBool( e->Iex.Const.con->Ico.U32 1173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng == 0xFFFFFFFF); 1174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ico_U64: return toBool( e->Iex.Const.con->Ico.U64 1175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng == 0xFFFFFFFFFFFFFFFFULL); 1176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: ppIRExpr(e); vpanic("isOnesU"); 1177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool notBool ( Bool b ) 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b == True) return False; 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b == False) return True; 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("notBool"); 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a zero which has the same type as the result of the given 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown primop. */ 1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* mkZeroOfPrimopResultType ( IROp op ) 1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 1192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE32: return IRExpr_Const(IRConst_U1(toBool(0))); 1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor8: return IRExpr_Const(IRConst_U8(0)); 1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor16: return IRExpr_Const(IRConst_U16(0)); 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sub32: 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor32: return IRExpr_Const(IRConst_U32(0)); 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sub64: 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor64: return IRExpr_Const(IRConst_U64(0)); 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_XorV128: return IRExpr_Const(IRConst_V128(0)); 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: vpanic("mkZeroOfPrimopResultType: bad primop"); 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a value containing all 1-bits, which has the same type as the 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result of the given primop. */ 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* mkOnesOfPrimopResultType ( IROp op ) 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 1209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32: 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ64: 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Const(IRConst_U1(toBool(1))); 1212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or8: 1213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRExpr_Const(IRConst_U8(0xFF)); 1214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or16: 1215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRExpr_Const(IRConst_U16(0xFFFF)); 1216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or32: 1217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRExpr_Const(IRConst_U32(0xFFFFFFFF)); 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ8x8: 1219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or64: 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Const(IRConst_U64(0xFFFFFFFFFFFFFFFFULL)); 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ8x16: 1222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ16x8: 1223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32x4: 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Const(IRConst_V128(0xFFFF)); 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIROp(op); 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("mkOnesOfPrimopResultType: bad primop"); 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Helpers for folding Clz32/64. */ 1232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt fold_Clz64 ( ULong value ) 1233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt i; 1235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(value != 0ULL); /* no defined semantics for arg==0 */ 1236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < 64; ++i) { 1237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0ULL != (value & (((ULong)1) << (63 - i)))) return i; 1238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(0); 1240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /*NOTREACHED*/ 1241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UInt fold_Clz32 ( UInt value ) 1245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt i; 1247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(value != 0); /* no defined semantics for arg==0 */ 1248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < 32; ++i) { 1249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 != (value & (((UInt)1) << (31 - i)))) return i; 1250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vassert(0); 1252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /*NOTREACHED*/ 1253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* V64 holds 8 summary-constant bits in V128/V256 style. Convert to 1257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the corresponding real constant. */ 1258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng//XXX re-check this before use 1259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng//static ULong de_summarise_V64 ( UChar v64 ) 1260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng//{ 1261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// ULong r = 0; 1262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<0)) r |= 0x00000000000000FFULL; 1263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<1)) r |= 0x000000000000FF00ULL; 1264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<2)) r |= 0x0000000000FF0000ULL; 1265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<3)) r |= 0x00000000FF000000ULL; 1266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<4)) r |= 0x000000FF00000000ULL; 1267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<5)) r |= 0x0000FF0000000000ULL; 1268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<6)) r |= 0x00FF000000000000ULL; 1269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// if (v64 & (1<<7)) r |= 0xFF00000000000000ULL; 1270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// return r; 1271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng//} 1272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic IRExpr* fold_Expr ( IRExpr** env, IRExpr* e ) 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int shift; 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* e2 = e; /* e2 is the result of folding e, if possible */ 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->tag) { 1279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Unop: 1280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* UNARY ops */ 1281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->Iex.Unop.arg->tag == Iex_Const) { 1282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (e->Iex.Unop.op) { 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Uto8: 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 1 : 0))); 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Uto32: 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 1 : 0)); 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Uto64: 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 1 : 0)); 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Sto8: 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFF : 0))); 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Sto16: 1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16(toUShort( 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFFF : 0))); 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Sto32: 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFFFFFFF : 0)); 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Sto64: 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? 0xFFFFFFFFFFFFFFFFULL : 0)); 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_8Sto32: { 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* signed */ Int s32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U8; 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s32 <<= 24; 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s32 >>= 24; 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32((UInt)s32)); 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_16Sto32: { 1328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* signed */ Int s32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s32 <<= 16; 1330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s32 >>= 16; 1331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U32( (UInt)s32) ); 1332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_8Uto64: 1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFFULL & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_16Uto64: 1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFFFFULL & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)); 1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_8Uto32: 1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_8Sto16: { 1347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* signed */ Short s16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U8; 1348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s16 <<= 8; 1349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s16 >>= 8; 1350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U16( (UShort)s16) ); 1351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_8Uto16: 1354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U16( 1355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 1356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_16Uto32: 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)); 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32to16: 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16(toUShort( 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32to8: 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32to1: 1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1 == (1 & e->Iex.Unop.arg->Iex.Const.con->Ico.U32) 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ))); 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to1: 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1 == (1 & e->Iex.Unop.arg->Iex.Const.con->Ico.U64) 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ))); 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_NotV128: 1381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128( 1382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.V128))); 1383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Not64: 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U64))); 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Not32: 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Not16: 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16(toUShort( 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U16)))); 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Not8: 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U8)))); 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Not1: 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1( 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown notBool(e->Iex.Unop.arg->Iex.Const.con->Ico.U1))); 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to8: { 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 &= 0xFFULL; 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8( (UChar)w64 )); 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to16: { 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 &= 0xFFFFULL; 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16( (UShort)w64 )); 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to32: { 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 &= 0x00000000FFFFFFFFULL; 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( (UInt)w64 )); 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64HIto32: { 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 >>= 32; 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( (UInt)w64 )); 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32Uto64: 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0xFFFFFFFFULL 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & e->Iex.Unop.arg->Iex.Const.con->Ico.U32)); 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_16Sto64: { 1436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* signed */ Long s64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s64 <<= 48; 1438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s64 >>= 48; 1439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U64((ULong)s64)); 1440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32Sto64: { 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* signed */ Long s64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s64 <<= 32; 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s64 >>= 32; 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64((ULong)s64)); 1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_16to8: { 1451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UShort w16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w16 &= 0xFF; 1453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U8( (UChar)w16 )); 1454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_16HIto8: { 1457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UShort w16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w16 >>= 8; 1459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov w16 &= 0xFF; 1460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U8( (UChar)w16 )); 1461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNEZ8: 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0 != 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8) 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ))); 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNEZ32: 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0 != 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (0xFFFFFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32) 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ))); 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNEZ64: 1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0ULL != e->Iex.Unop.arg->Iex.Const.con->Ico.U64 1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ))); 1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpwNEZ32: { 1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt w32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w32 == 0) 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 0 )); 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 0xFFFFFFFF )); 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpwNEZ64: { 1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w64 == 0) 1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 0 )); 1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 0xFFFFFFFFFFFFFFFFULL )); 1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Left32: { 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s32 = (Int)(u32 & 0xFFFFFFFF); 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s32 = (s32 | (-s32)); 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const( IRConst_U32( (UInt)s32 )); 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Left64: { 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long s64 = (Long)u64; 1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s64 = (s64 | (-s64)); 1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const( IRConst_U64( (ULong)s64 )); 1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_Clz32: { 1516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (u32 != 0) 1518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U32(fold_Clz32(u32))); 1519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_Clz64: { 1522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (u64 != 0ULL) 1524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U64(fold_Clz64(u64))); 1525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1528663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For these vector ones, can't fold all cases, but at least 1529663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do the most obvious one. Could do better here using 1530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng summarise/desummarise of vector constants, but too 1531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng difficult to verify; hence just handle the zero cases. */ 1532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_32UtoV128: { 1533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == u32) { 1535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128(0x0000)); 1536663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_V128to64: { 1542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort v128 = e->Iex.Unop.arg->Iex.Const.con->Ico.V128; 1543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == ((v128 >> 0) & 0xFF)) { 1544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_U64(0)); 1545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1547663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_V128HIto64: { 1551663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort v128 = e->Iex.Unop.arg->Iex.Const.con->Ico.V128; 1552663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == ((v128 >> 8) & 0xFF)) { 1553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_U64(0)); 1554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1559663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64UtoV128: { 1560663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == u64) { 1562663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128(0x0000)); 1563663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1564663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1565663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1568663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1569663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Even stupider (although still correct ..) */ 1570663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_V256to64_0: case Iop_V256to64_1: 1571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_V256to64_2: case Iop_V256to64_3: { 1572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UInt v256 = e->Iex.Unop.arg->Iex.Const.con->Ico.V256; 1573663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (v256 == 0x00000000) { 1574663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_U64(0)); 1575663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1576663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1579663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1580663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto unhandled; 1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1584663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1585663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1587663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Binop: 1588663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* BINARY ops */ 1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Binop.arg1->tag == Iex_Const 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg2->tag == Iex_Const) { 1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* cases where both args are consts */ 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->Iex.Binop.op) { 1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Or -- */ 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Or8: 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Or16: 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16(toUShort( 1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Or32: 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Or64: 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1615663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_OrV128: 1616663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128( 1617663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 1618663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng | e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 1619663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Xor -- */ 1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor8: 1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor16: 1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U16(toUShort( 1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor32: 1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Xor64: 1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1642663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_XorV128: 1643663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128( 1644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 1645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 1646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- And -- */ 1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_And8: 1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_And16: 1655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U16(toUShort( 1656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 1657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov & e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 1658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_And32: 1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_And64: 1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown & e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1669663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AndV128: 1670663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128( 1671663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng & e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 1673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Add -- */ 1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Add8: 1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Add32: 1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Add64: 1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Sub -- */ 1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sub8: 1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U8(toUChar( 1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sub32: 1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sub64: 1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Max32U -- */ 1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Max32U: { 1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt res = u32a > u32b ? u32a : u32b; 1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32(res)); 1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Mul -- */ 1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Mul32: 1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Mul64: 1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_MullS32: { 1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* very paranoid */ 1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s32a = (Int)u32a; 1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s32b = (Int)u32b; 1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long s64a = (Long)s32a; 1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long s64b = (Long)s32b; 1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long sres = s64a * s64b; 1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong ures = (ULong)sres; 1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64(ures)); 1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Shl -- */ 1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Shl32: 1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 31) 1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32( 1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown << shift))); 1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Shl64: 1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 63) 1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown << shift))); 1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Sar -- */ 1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sar32: { 1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* paranoid ... */ 1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*signed*/ Int s32; 1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s32 = (Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32); 1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 31) { 1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s32 >>=/*signed*/ shift; 1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32((UInt)s32)); 1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Sar64: { 1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* paranoid ... */ 1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*signed*/ Long s64; 1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s64 = (Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64); 1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 63) { 1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s64 >>=/*signed*/ shift; 1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64((ULong)s64)); 1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Shr -- */ 1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Shr32: { 1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* paranoid ... */ 1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*unsigned*/ UInt u32; 1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u32 = (UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32); 1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 31) { 1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u32 >>=/*unsigned*/ shift; 1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32(u32)); 1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Shr64: { 1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* paranoid ... */ 1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*unsigned*/ ULong u64; 1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u64 = (ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64); 1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift >= 0 && shift <= 63) { 1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown u64 >>=/*unsigned*/ shift; 1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64(u64)); 1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpEQ -- */ 1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ32: 1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))); 1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ64: 1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)))); 1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpNE -- */ 1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNE8: 1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((0xFF & e->Iex.Binop.arg1->Iex.Const.con->Ico.U8) 1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown != (0xFF & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))))); 1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNE32: 1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown != e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))); 1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNE64: 1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown != e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)))); 1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpLEU -- */ 1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpLE32U: 1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <= (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpLE64U: 1850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U1(toBool( 1851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 1852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov <= (ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 1853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpLES -- */ 1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpLE32S: 1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <= (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1861b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpLE64S: 1862b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U1(toBool( 1863b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 1864b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov <= (Long)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 1865b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpLTS -- */ 1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpLT32S: 1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown < (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpLT64S: 1874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U1(toBool( 1875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 1876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov < (Long)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 1877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpLTU -- */ 1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpLT32U: 1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U1(toBool( 1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown < (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpLT64U: 1886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov e2 = IRExpr_Const(IRConst_U1(toBool( 1887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 1888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov < (ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 1889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- CmpORD -- */ 1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpORD32S: { 1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* very paranoid */ 1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s32a = (Int)u32a; 1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s32b = (Int)u32b; 1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int r = 0x2; /* EQ */ 1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s32a < s32b) { 1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r = 0x8; /* LT */ 1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (s32a > s32b) { 1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r = 0x4; /* GT */ 1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U32(r)); 1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- nHLto2n -- */ 1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32HLto64: 1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = IRExpr_Const(IRConst_U64( 1912663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (((ULong)(e->Iex.Binop.arg1 1913663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ->Iex.Const.con->Ico.U32)) << 32) 1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown | ((ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) 1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown )); 1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64HLto128: 1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We can't fold this, because there is no way to 1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown express he result in IR, but at least pretend to 1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handle it, so as to stop getting blasted with 1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no-rule-for-this-primop messages. */ 1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1923663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For this vector one, can't fold all cases, but at 1924663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng least do the most obvious one. Could do better here 1925663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng using summarise/desummarise of vector constants, but 1926663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng too difficult to verify; hence just handle the zero 1927663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cases. */ 1928663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_64HLtoV128: { 1929663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong argHi = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; 1930663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong argLo = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; 1931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == argHi && 0 == argLo) { 1932663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128(0)); 1933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* -- V128 stuff -- */ 1940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_InterleaveLO8x16: { 1941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* This turns up a lot in Memcheck instrumentation of 1942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Icc generated code. I don't know why. */ 1943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort arg1 = e->Iex.Binop.arg1->Iex.Const.con->Ico.V128; 1944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UShort arg2 = e->Iex.Binop.arg2->Iex.Const.con->Ico.V128; 1945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0 == arg1 && 0 == arg2) { 1946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Const(IRConst_V128(0)); 1947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto unhandled; 1949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto unhandled; 1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* other cases (identities, etc) */ 1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->Iex.Binop.op) { 1961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shl32: 1963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shl64: 1964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shr64: 1965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Shl32/Shl64/Shr64(x,0) ==> x */ 1966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg2)) { 1967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 1968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Shl32/Shl64/Shr64(0,x) ==> 0 */ 1971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg1)) { 1972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 1973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Shr32: 1978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Shr32(x,0) ==> x */ 1979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg2)) { 1980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 1981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or8: 1986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or16: 1987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or32: 1988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Or64: 1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Max32U: 1990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Or8/Or16/Or32/Or64/Max32U(x,0) ==> x */ 1991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg2)) { 1992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 1993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Or8/Or16/Or32/Or64/Max32U(0,x) ==> x */ 1996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg1)) { 1997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg2; 1998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Or8/Or16/Or32/Or64/Max32U(x,1---1b) ==> 1---1b */ 2001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Or8/Or16/Or32/Or64/Max32U(1---1b,x) ==> 1---1b */ 2002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isOnesU(e->Iex.Binop.arg1) || isOnesU(e->Iex.Binop.arg2)) { 2003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = mkOnesOfPrimopResultType(e->Iex.Binop.op); 2004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Or8/Or16/Or32/Or64/Max32U(t,t) ==> t, for some IRTemp t */ 2007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = e->Iex.Binop.arg1; 2009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Add8: 2014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add8(t,t) ==> t << 1. 2015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Memcheck doesn't understand that 2016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x+x produces a defined least significant bit, and it seems 2017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng simplest just to get rid of the problem by rewriting it 2018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng out, since the opportunity to do so exists. */ 2019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Binop(Iop_Shl8, e->Iex.Binop.arg1, 2021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Const(IRConst_U8(1))); 2022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* NB no Add16(t,t) case yet as no known test case exists */ 2027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Add32: 2029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Add64: 2030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add32/Add64(x,0) ==> x */ 2031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg2)) { 2032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add32/Add64(0,x) ==> x */ 2036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU(e->Iex.Binop.arg1)) { 2037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg2; 2038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Add32/Add64(t,t) ==> t << 1. Same rationale as for Add8. */ 2041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = IRExpr_Binop( 2043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.op == Iop_Add32 ? Iop_Shl32 : Iop_Shl64, 2044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.arg1, IRExpr_Const(IRConst_U8(1))); 2045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sub64: 2050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Sub64(x,0) ==> x */ 2051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU64(e->Iex.Binop.arg2)) { 2052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Sub64(t,t) ==> 0, for some IRTemp t */ 2056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2057663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And32: 2063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And32(x,0xFFFFFFFF) ==> x */ 2064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isOnesU32(e->Iex.Binop.arg2)) { 2065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And32(x,0) ==> 0 */ 2069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU32(e->Iex.Binop.arg2)) { 2070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg2; 2071663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2072663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2073663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And32(0,x) ==> 0 */ 2074663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (isZeroU32(e->Iex.Binop.arg1)) { 2075663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2076663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And32(t,t) ==> t, for some IRTemp t */ 2079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And8: 2086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And16: 2087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_And64: 2088663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AndV128: 2089663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_AndV256: 2090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And8/And16/And64/AndV128/AndV256(t,t) 2091663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ==> t, for some IRTemp t */ 2092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2094663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2095663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2096663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2097663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2098663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_OrV128: 2099663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_OrV256: 2100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* V128/V256(t,t) ==> t, for some IRTemp t */ 2101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = e->Iex.Binop.arg1; 2103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor8: 2108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor16: 2109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor32: 2110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Xor64: 2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_XorV128: 2112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Xor8/16/32/64/V128(t,t) ==> 0, for some IRTemp t */ 2113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_Sub32: 2120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpNE32: 2121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Sub32/CmpNE32(t,t) ==> 0, for some IRTemp t */ 2122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32: 2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ64: 2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ8x8: 2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpEQ8x16: 2132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ16x8: 2133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iop_CmpEQ32x4: 2134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = mkOnesOfPrimopResultType(e->Iex.Binop.op); 2136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Mux0X: 2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Mux0X */ 2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* is the discriminant is a constant? */ 2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Mux0X.cond->tag == Iex_Const) { 2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool zero; 2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* assured us by the IR type rules */ 2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(e->Iex.Mux0X.cond->Iex.Const.con->tag == Ico_U8); 2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zero = toBool(0 == (0xFF & e->Iex.Mux0X.cond 2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ->Iex.Const.con->Ico.U8)); 2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = zero ? e->Iex.Mux0X.expr0 : e->Iex.Mux0X.exprX; 2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* are the arms identical? (pretty weedy test) */ 2160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (sameIRExprs(env, e->Iex.Mux0X.expr0, 2161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Mux0X.exprX)) { 2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = e->Iex.Mux0X.expr0; 2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* not considered */ 2168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Show cases where we've found but not folded 'op(t,t)'. Be 2172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng careful not to call sameIRExprs with values of different types, 2173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng though, else it will assert (and so it should!). We can't 2174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng conveniently call typeOfIRExpr on the two args without a whole 2175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bunch of extra plumbing to pass in a type env, so just use a 2176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hacky test to check the arguments are not anything that might 2177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sameIRExprs to assert. This is only OK because this kludge is 2178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng only used for debug printing, not for "real" operation. For 2179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "real" operation (ie, all other calls to sameIRExprs), it is 2180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng essential that the to args have the same type. 2181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng The "right" solution is to plumb the containing block's 2183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTypeEnv through to here and use typeOfIRExpr to be sure. But 2184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng that's a bunch of extra parameter passing which will just slow 2185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng down the normal case, for no purpose. */ 2186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_control.iropt_verbosity > 0 2187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e == e2 2188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && e->tag == Iex_Binop 2189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && !debug_only_hack_sameIRExprs_might_assert(e->Iex.Binop.arg1, 2190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Binop.arg2) 2191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("vex iropt: fold_Expr: no ident rule for: "); 2193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ppIRExpr(e); 2194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("\n"); 2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Show the overall results of folding. */ 2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT && e2 != e) { 2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("FOLD: "); 2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(e); vex_printf(" -> "); 2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(e2); vex_printf("\n"); 2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e2; 2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unhandled: 2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if 0 2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n\n"); 2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(e); 2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("fold_Expr: no rule for the above"); 2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) { 2213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("vex iropt: fold_Expr: no const rule for: "); 2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(e); 2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e2; 2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Apply the subst to a simple 1-level expression -- guaranteed to be 2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1-level due to previous flattening pass. */ 2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* subst_Expr ( IRExpr** env, IRExpr* ex ) 2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (ex->tag) { 2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[(Int)ex->Iex.RdTmp.tmp] != NULL) { 2230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr *rhs = env[(Int)ex->Iex.RdTmp.tmp]; 2231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (rhs->tag == Iex_RdTmp) 2232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return rhs; 2233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (rhs->tag == Iex_Const 2234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && rhs->Iex.Const.con->tag != Ico_F64i) 2235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return rhs; 2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* not bound in env */ 2238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ex; 2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ex; 2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.GetI.ix)); 2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_GetI( 2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.GetI.descr, 2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.GetI.ix), 2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.GetI.bias 2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Qop: { 2253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRQop* qop = ex->Iex.Qop.details; 2254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(qop->arg1)); 2255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(qop->arg2)); 2256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(qop->arg3)); 2257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(qop->arg4)); 2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Qop( 2259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng qop->op, 2260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, qop->arg1), 2261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, qop->arg2), 2262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, qop->arg3), 2263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, qop->arg4) 2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Iex_Triop: { 2268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRTriop* triop = ex->Iex.Triop.details; 2269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(triop->arg1)); 2270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(triop->arg2)); 2271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(triop->arg3)); 2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Triop( 2273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng triop->op, 2274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, triop->arg1), 2275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, triop->arg2), 2276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng subst_Expr(env, triop->arg3) 2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Binop.arg1)); 2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Binop.arg2)); 2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Binop( 2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.Binop.op, 2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Binop.arg1), 2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Binop.arg2) 2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Unop.arg)); 2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( 2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.Unop.op, 2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Unop.arg) 2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Load.addr)); 2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Load( 2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.Load.end, 2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.Load.ty, 2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Load.addr) 2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: { 2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args2 = shallowCopyIRExprVec(ex->Iex.CCall.args); 2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; args2[i]; i++) { 2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(args2[i])); 2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args2[i] = subst_Expr(env, args2[i]); 2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_CCall( 2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.CCall.cee, 2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex->Iex.CCall.retty, 2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args2 2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Mux0X.cond)); 2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Mux0X.expr0)); 2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ex->Iex.Mux0X.exprX)); 2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Mux0X( 2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Mux0X.cond), 2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Mux0X.expr0), 2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_Expr(env, ex->Iex.Mux0X.exprX) 2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n\n"); ppIRExpr(ex); 2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("subst_Expr"); 2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Apply the subst to stmt, then fold the result as much as possible. 2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Much simplified due to stmt being previously flattened. As a 2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result of this, the stmt may wind up being turned into a no-op. 2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRStmt* subst_and_fold_Stmt ( IRExpr** env, IRStmt* st ) 2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if 0 2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\nsubst and fold stmt\n"); 2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.base)); 2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.nia)); 2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_AbiHint( 2353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.AbiHint.base)), 2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.AbiHint.len, 2355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.AbiHint.nia)) 2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Put.data)); 2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Put( 2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Put.offset, 2361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.Put.data)) 2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_PutI: { 2365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti, *puti2; 2366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti = st->Ist.PutI.details; 2367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(puti->ix)); 2368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(puti->data)); 2369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti2 = mkIRPutI(puti->descr, 2370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, puti->ix)), 2371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->bias, 2372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, puti->data))); 2373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRStmt_PutI(puti2); 2374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is the one place where an expr (st->Ist.WrTmp.data) is 2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allowed to be more than just a constant or a tmp. */ 2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_WrTmp( 2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.tmp, 2381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.WrTmp.data)) 2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.addr)); 2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.data)); 2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Store( 2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Store.end, 2389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.Store.addr)), 2390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.Store.data)) 2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: { 2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS *cas, *cas2; 2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->addr)); 2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(cas->expdHi == NULL || isIRAtom(cas->expdHi)); 2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->expdLo)); 2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(cas->dataHi == NULL || isIRAtom(cas->dataHi)); 2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->dataLo)); 2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas2 = mkIRCAS( 2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas->oldHi, cas->oldLo, cas->end, 2403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, cas->addr)), 2404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cas->expdHi ? fold_Expr(env, subst_Expr(env, cas->expdHi)) 2405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : NULL, 2406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, cas->expdLo)), 2407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cas->dataHi ? fold_Expr(env, subst_Expr(env, cas->dataHi)) 2408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : NULL, 2409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, cas->dataLo)) 2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_CAS(cas2); 2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.LLSC.addr)); 2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.LLSC.storedata) 2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.LLSC.storedata)); 2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_LLSC( 2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.end, 2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.result, 2421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fold_Expr(env, subst_Expr(env, st->Ist.LLSC.addr)), 2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.storedata 2423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? fold_Expr(env, subst_Expr(env, st->Ist.LLSC.storedata)) 2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : NULL 2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: { 2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty *d, *d2; 2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2 = emptyIRDirty(); 2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d2 = *d; 2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->args = shallowCopyIRExprVec(d2->args); 2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d2->mFx != Ifx_None) { 2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d2->mAddr)); 2436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d2->mAddr = fold_Expr(env, subst_Expr(env, d2->mAddr)); 2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d2->guard)); 2439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d2->guard = fold_Expr(env, subst_Expr(env, d2->guard)); 2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d2->args[i]; i++) { 2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d2->args[i])); 2442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng d2->args[i] = fold_Expr(env, subst_Expr(env, d2->args[i])); 2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Dirty(d2); 2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 2448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return IRStmt_IMark(st->Ist.IMark.addr, 2449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov st->Ist.IMark.len, 2450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov st->Ist.IMark.delta); 2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_NoOp(); 2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_MBE(st->Ist.MBE.event); 2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: { 2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* fcond; 2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Exit.guard)); 2461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fcond = fold_Expr(env, subst_Expr(env, st->Ist.Exit.guard)); 2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fcond->tag == Iex_Const) { 2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Interesting. The condition on this exit has folded down to 2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a constant. */ 2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(fcond->Iex.Const.con->tag == Ico_U1); 2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(fcond->Iex.Const.con->Ico.U1 == False 2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || fcond->Iex.Const.con->Ico.U1 == True); 2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fcond->Iex.Const.con->Ico.U1 == False) { 2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* exit is never going to happen, so dump the statement. */ 2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_NoOp(); 2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(fcond->Iex.Const.con->Ico.U1 == True); 2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Hmmm. The exit has become unconditional. Leave it 2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as it is for now, since we'd have to truncate the BB 2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown at this point, which is tricky. Such truncation is 2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown done later by the dead-code elimination pass. */ 2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* fall out into the reconstruct-the-exit code. */ 2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) 2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* really a misuse of vex_control.iropt_verbosity */ 2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex iropt: IRStmt_Exit became unconditional\n"); 2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRStmt_Exit(fcond, st->Ist.Exit.jk, 2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->Ist.Exit.dst, st->Ist.Exit.offsIP); 2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRStmt(st); 2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("subst_and_fold_Stmt"); 2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* cprop_BB ( IRSB* in ) 2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* out; 2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st2; 2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_tmps = in->tyenv->types_used; 2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** env = LibVEX_Alloc(n_tmps * sizeof(IRExpr*)); 2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out = emptyIRSB(); 2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->tyenv = deepCopyIRTypeEnv( in->tyenv ); 2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Set up the env with which travels forward. This holds a 2506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng substitution, mapping IRTemps to IRExprs. The environment 2507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng is to be applied as we move along. Keys are IRTemps. 2508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Values are IRExpr*s. 2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n_tmps; i++) 2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[i] = NULL; 2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* For each original SSA-form stmt ... */ 2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < in->stmts_used; i++) { 2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First apply the substitution to the current stmt. This 2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown propagates in any constants and tmp-tmp assignments 2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown accumulated prior to this point. As part of the subst_Stmt 2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown call, also then fold any constant expressions resulting. */ 2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st2 = in->stmts[i]; 2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* perhaps st2 is already a no-op? */ 2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st2->tag == Ist_NoOp) continue; 2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st2 = subst_and_fold_Stmt( env, st2 ); 2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the statement has been folded into a no-op, forget it. */ 2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st2->tag == Ist_NoOp) continue; 2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* If the statement assigns to an IRTemp add it to the running 2532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng environment. This is for the benefit of copy propagation 2533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and to allow sameIRExpr look through IRTemps. */ 2534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (st2->tag == Ist_WrTmp) { 2535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(env[(Int)(st2->Ist.WrTmp.tmp)] == NULL); 2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[(Int)(st2->Ist.WrTmp.tmp)] = st2->Ist.WrTmp.data; 2537663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2538663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 't1 = t2' -- don't add to BB; will be optimized out */ 2539663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (st2->Ist.WrTmp.data->tag == Iex_RdTmp) continue; 2540663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2541663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 't = const' && 'const != F64i' -- don't add to BB 2542663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Note, we choose not to propagate const when const is an 2543663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng F64i, so that F64i literals can be CSE'd later. This helps 2544663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng x86 floating point code generation. */ 2545663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (st2->Ist.WrTmp.data->tag == Iex_Const 2546663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && st2->Ist.WrTmp.data->Iex.Const.con->tag != Ico_F64i) continue; 2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2548663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2549663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Not interesting, copy st2 into the output block. */ 2550663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addStmtToIRSB( out, st2 ); 2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2553663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if STATS_IROPT 2554663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vex_printf("sameIRExpr: invoked = %u/%u equal = %u/%u max_nodes = %u\n", 2555663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng invocation_count, recursion_count, success_count, 2556663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng recursion_success_count, max_nodes_visited); 2557663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 2558663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->next = subst_Expr( env, in->next ); 2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out->jumpkind = in->jumpkind; 2561663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng out->offsIP = in->offsIP; 2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return out; 2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Dead code (t = E) removal ---*/ 2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* As a side effect, also removes all code following an unconditional 2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown side exit. */ 2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The type of the HashHW map is: a map from IRTemp to nothing 2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -- really just operating a set or IRTemps. 2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browninline 2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addUses_Temp ( Bool* set, IRTemp tmp ) 2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[(Int)tmp] = True; 2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addUses_Expr ( Bool* set, IRExpr* e ) 2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.GetI.ix); 2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Mux0X.cond); 2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Mux0X.expr0); 2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Mux0X.exprX); 2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; e->Iex.CCall.args[i]; i++) 2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.CCall.args[i]); 2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Load.addr); 2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Qop: 2603663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Qop.details->arg1); 2604663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Qop.details->arg2); 2605663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Qop.details->arg3); 2606663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Qop.details->arg4); 2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Triop: 2609663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Triop.details->arg1); 2610663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Triop.details->arg2); 2611663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, e->Iex.Triop.details->arg3); 2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Binop.arg1); 2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Binop.arg2); 2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, e->Iex.Unop.arg); 2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Temp(set, e->Iex.RdTmp.tmp); 2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(e); 2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("addUses_Expr"); 2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addUses_Stmt ( Bool* set, IRStmt* st ) 2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d; 2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS* cas; 2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.AbiHint.base); 2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.AbiHint.nia); 2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 2644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, st->Ist.PutI.details->ix); 2645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng addUses_Expr(set, st->Ist.PutI.details->data); 2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.WrTmp.data); 2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.Put.data); 2652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.Store.addr); 2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.Store.data); 2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, cas->addr); 2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cas->expdHi) 2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, cas->expdHi); 2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, cas->expdLo); 2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cas->dataHi) 2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, cas->dataHi); 2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, cas->dataLo); 2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.LLSC.addr); 2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.LLSC.storedata) 2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.LLSC.storedata); 2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->mFx != Ifx_None) 2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, d->mAddr); 2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, d->guard); 2677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d->args[i] != NULL; i++) 2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, d->args[i]); 2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 2681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, st->Ist.Exit.guard); 2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("addUses_Stmt"); 2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this literally IRExpr_Const(IRConst_U1(False)) ? */ 2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool isZeroU1 ( IRExpr* e ) 2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( e->tag == Iex_Const 2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->tag == Ico_U1 2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->Ico.U1 == False ); 2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this literally IRExpr_Const(IRConst_U1(True)) ? */ 2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool isOneU1 ( IRExpr* e ) 2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( e->tag == Iex_Const 2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->tag == Ico_U1 2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->Ico.U1 == True ); 2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note, this destructively modifies the given IRSB. */ 2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scan backwards through statements, carrying a set of IRTemps which 2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are known to be used after the current point. On encountering 't = 2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown E', delete the binding if it is not used. Otherwise, add any temp 2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uses to the set and keep on moving backwards. 2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown As an enhancement, the first (backwards) pass searches for IR exits 2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with always-taken conditions and notes the location of the earliest 2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown one in the block. If any such are found, a second pass copies the 2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit destination and jump kind to the bb-end. Then, the exit and 2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown all statements following it are turned into no-ops. 2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* notstatic */ void do_deadcode_BB ( IRSB* bb ) 2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, i_unconditional_exit; 2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_tmps = bb->tyenv->types_used; 2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool* set = LibVEX_Alloc(n_tmps * sizeof(Bool)); 2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n_tmps; i++) 2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[i] = False; 2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* start off by recording IRTemp uses in the next field. */ 2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Expr(set, bb->next); 2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First pass */ 2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Work backwards through the stmts */ 2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i_unconditional_exit = -1; 2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb->stmts_used-1; i >= 0; i--) { 2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* take note of any unconditional exits */ 2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Exit 2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isOneU1(st->Ist.Exit.guard)) 2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i_unconditional_exit = i; 2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp 2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && set[(Int)(st->Ist.WrTmp.tmp)] == False) { 2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* it's an IRTemp which never got used. Delete it. */ 2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("DEAD: "); 2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_NoOp(); 2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Dirty 2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.Dirty.details->guard 2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isZeroU1(st->Ist.Dirty.details->guard)) { 2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is a dirty helper which will never get called. 2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Delete it. */ 2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_NoOp(); 2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note any IRTemp uses made by the current statement. */ 2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addUses_Stmt(set, st); 2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Optional second pass: if any unconditional exits were found, 2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete them and all following statements. */ 2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (i_unconditional_exit != -1) { 2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) vex_printf("ZAPPING ALL FORWARDS from %d\n", 2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i_unconditional_exit); 2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(i_unconditional_exit >= 0 2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && i_unconditional_exit < bb->stmts_used); 2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->next 2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = IRExpr_Const( bb->stmts[i_unconditional_exit]->Ist.Exit.dst ); 2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->jumpkind 2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = bb->stmts[i_unconditional_exit]->Ist.Exit.jk; 2787663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bb->offsIP 2788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = bb->stmts[i_unconditional_exit]->Ist.Exit.offsIP; 2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = i_unconditional_exit; i < bb->stmts_used; i++) 2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_NoOp(); 2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Specialisation of helper function calls, in ---*/ 2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- collaboration with the front end ---*/ 2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* spec_helpers_BB( 2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb, 2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int) 2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* ex; 2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool any = False; 2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb->stmts_used-1; i >= 0; i--) { 2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag != Ist_WrTmp 2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->Ist.WrTmp.data->tag != Iex_CCall) 2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ex = (*specHelper)( st->Ist.WrTmp.data->Iex.CCall.cee->name, 2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.data->Iex.CCall.args, 2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &bb->stmts[0], i ); 2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!ex) 2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* the front end can't think of a suitable replacement */ 2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We got something better. Install it in the bb. */ 2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any = True; 2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] 2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = IRStmt_WrTmp(st->Ist.WrTmp.tmp, ex); 2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) { 2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("SPEC: "); 2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(st->Ist.WrTmp.data); 2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" --> "); 2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(ex); 2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (any) 2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = flatten_BB(bb); 2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bb; 2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Determination of guest state aliasing relationships ---*/ 2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These are helper functions for CSE and GetI/PutI transformations. 2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Determine, to the extent possible, the relationship between two 2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guest state accesses. The possible outcomes are: 2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Exact alias. These two accesses denote precisely the same 2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown piece of the guest state. 2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Definitely no alias. These two accesses are guaranteed not to 2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlap any part of the guest state. 2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Unknown -- if neither of the above can be established. 2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If in doubt, return Unknown. */ 2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { ExactAlias, NoAlias, UnknownAlias } 2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GSAliasing; 2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Produces the alias relation between an indexed guest 2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state access and a non-indexed access. */ 2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGSAliasing getAliasingRelation_IC ( IRRegArray* descr1, IRExpr* ix1, 2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int offset2, IRType ty2 ) 2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt minoff1, maxoff1, minoff2, maxoff2; 2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getArrayBounds( descr1, &minoff1, &maxoff1 ); 2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown minoff2 = offset2; 2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown maxoff2 = minoff2 + sizeofIRType(ty2) - 1; 2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (maxoff1 < minoff2 || maxoff2 < minoff1) 2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NoAlias; 2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Could probably do better here if required. For the moment 2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown however just claim not to know anything more. */ 2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return UnknownAlias; 2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Produces the alias relation between two indexed guest state 2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown accesses. */ 2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGSAliasing getAliasingRelation_II ( 2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descr1, IRExpr* ix1, Int bias1, 2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descr2, IRExpr* ix2, Int bias2 2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt minoff1, maxoff1, minoff2, maxoff2; 2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int iters; 2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First try hard to show they don't alias. */ 2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getArrayBounds( descr1, &minoff1, &maxoff1 ); 2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getArrayBounds( descr2, &minoff2, &maxoff2 ); 2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (maxoff1 < minoff2 || maxoff2 < minoff1) 2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NoAlias; 2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So the two arrays at least partially overlap. To get any 2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown further we'll have to be sure that the descriptors are 2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identical. */ 2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!eqIRRegArray(descr1, descr2)) 2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return UnknownAlias; 2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The descriptors are identical. Now the only difference can be 2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the index expressions. If they cannot be shown to be 2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identical, we have to say we don't know what the aliasing 2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation will be. Now, since the IR is flattened, the index 2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expressions should be atoms -- either consts or tmps. So that 2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown makes the comparison simple. */ 2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ix1)); 2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(ix2)); 2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!eqIRAtom(ix1,ix2)) 2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return UnknownAlias; 2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ok, the index expressions are identical. So now the only way 2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown they can be different is in the bias. Normalise this 2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paranoidly, to reliably establish equality/non-equality. */ 2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So now we know that the GetI and PutI index the same array 2931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with the same base. Are the offsets the same, modulo the 2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown array size? Do this paranoidly. */ 2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(descr1->nElems == descr2->nElems); 2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(descr1->elemTy == descr2->elemTy); 2935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(descr1->base == descr2->base); 2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iters = 0; 2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (bias1 < 0 || bias2 < 0) { 2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bias1 += descr1->nElems; 2939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bias2 += descr1->nElems; 2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown iters++; 2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iters > 10) 2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("getAliasingRelation: iters"); 2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(bias1 >= 0 && bias2 >= 0); 2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bias1 %= descr1->nElems; 2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bias2 %= descr1->nElems; 2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(bias1 >= 0 && bias1 < descr1->nElems); 2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(bias2 >= 0 && bias2 < descr1->nElems); 2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Finally, biasP and biasG are normalised into the range 2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0 .. descrP/G->nElems - 1. And so we can establish 2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown equality/non-equality. */ 2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bias1==bias2 ? ExactAlias : NoAlias; 2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Common Subexpression Elimination ---*/ 2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Expensive in time and space. */ 2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Uses two environments: 2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a IRTemp -> IRTemp mapping 2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a mapping from AvailExpr* to IRTemp 2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng enum { TCc, TCt } tag; 2972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng union { IRTemp tmp; IRConst* con; } u; 2973663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConst; 2975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2976663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool eqTmpOrConst ( TmpOrConst* tc1, TmpOrConst* tc2 ) 2977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tc1->tag != tc2->tag) 2979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return False; 2980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (tc1->tag) { 2981663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case TCc: 2982663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return eqIRConst(tc1->u.con, tc2->u.con); 2983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case TCt: 2984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return tc1->u.tmp == tc2->u.tmp; 2985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("eqTmpOrConst"); 2987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 2989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool eqIRCallee ( IRCallee* cee1, IRCallee* cee2 ) 2991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 2992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool eq = cee1->addr == cee2->addr; 2993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (eq) { 2994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(cee1->regparms == cee2->regparms); 2995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(cee1->mcx_mask == cee2->mcx_mask); 2996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Names should be the same too, but we don't bother to 2997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng check. */ 2998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return eq; 3000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3001663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Convert a NULL terminated IRExpr* vector to an array of 3003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConsts, and a length. */ 3004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void irExprVec_to_TmpOrConsts ( /*OUT*/TmpOrConst** outs, 3005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*OUT*/Int* nOuts, 3006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr** ins ) 3007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 3008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, n; 3009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* We have to make two passes, one to count, one to copy. */ 3010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (n = 0; ins[n]; n++) 3011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ; 3012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *outs = LibVEX_Alloc(n * sizeof(TmpOrConst)); 3013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *nOuts = n; 3014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* and now copy .. */ 3015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) { 3016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr* arg = ins[i]; 3017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConst* dst = &(*outs)[i]; 3018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (arg->tag == Iex_RdTmp) { 3019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst->tag = TCt; 3020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst->u.tmp = arg->Iex.RdTmp.tmp; 3021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if (arg->tag == Iex_Const) { 3023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst->tag = TCc; 3024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dst->u.con = arg->Iex.Const.con; 3025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else { 3027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Failure of this is serious; it means that the presented arg 3028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng isn't an IR atom, as it should be. */ 3029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vpanic("irExprVec_to_TmpOrConsts"); 3030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 3033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef 3035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct { 3036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng enum { Ut, Btt, Btc, Bct, Cf64i, Mttt, GetIt, CCall } tag; 3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unop(tmp) */ 3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; 3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp arg; 3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Ut; 3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* binop(tmp,tmp) */ 3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; 3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp arg1; 3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp arg2; 3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Btt; 3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* binop(tmp,const) */ 3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; 3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp arg1; 3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst con2; 3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Btc; 3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* binop(const,tmp) */ 3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IROp op; 3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst con1; 3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp arg2; 3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Bct; 3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* F64i-style const */ 3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong f64i; 3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Cf64i; 3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Mux0X(tmp,tmp,tmp) */ 3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp co; 3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp e0; 3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp eX; 3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Mttt; 3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* GetI(descr,tmp,bias)*/ 3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descr; 3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp ix; 3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int bias; 3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } GetIt; 3077663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Clean helper call */ 3078663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct { 3079663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRCallee* cee; 3080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConst* args; 3081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int nArgs; 3082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRType retty; 3083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } CCall; 3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } u; 3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AvailExpr; 3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool eq_AvailExpr ( AvailExpr* a1, AvailExpr* a2 ) 3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3090663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (LIKELY(a1->tag != a2->tag)) 3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (a1->tag) { 3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ut: 3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( 3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a1->u.Ut.op == a2->u.Ut.op 3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Ut.arg == a2->u.Ut.arg); 3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btt: 3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( 3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a1->u.Btt.op == a2->u.Btt.op 3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Btt.arg1 == a2->u.Btt.arg1 3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Btt.arg2 == a2->u.Btt.arg2); 3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btc: 3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( 3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a1->u.Btc.op == a2->u.Btc.op 3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Btc.arg1 == a2->u.Btc.arg1 3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && eqIRConst(&a1->u.Btc.con2, &a2->u.Btc.con2)); 3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Bct: 3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( 3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a1->u.Bct.op == a2->u.Bct.op 3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Bct.arg2 == a2->u.Bct.arg2 3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && eqIRConst(&a1->u.Bct.con1, &a2->u.Bct.con1)); 3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Cf64i: 3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool(a1->u.Cf64i.f64i == a2->u.Cf64i.f64i); 3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Mttt: 3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool(a1->u.Mttt.co == a2->u.Mttt.co 3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Mttt.e0 == a2->u.Mttt.e0 3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.Mttt.eX == a2->u.Mttt.eX); 3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case GetIt: 3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool(eqIRRegArray(a1->u.GetIt.descr, a2->u.GetIt.descr) 3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.GetIt.ix == a2->u.GetIt.ix 3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && a1->u.GetIt.bias == a2->u.GetIt.bias); 3122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case CCall: { 3123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, n; 3124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool eq = a1->u.CCall.nArgs == a2->u.CCall.nArgs 3125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && eqIRCallee(a1->u.CCall.cee, a2->u.CCall.cee); 3126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (eq) { 3127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng n = a1->u.CCall.nArgs; 3128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) { 3129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (!eqTmpOrConst( &a1->u.CCall.args[i], 3130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &a2->u.CCall.args[i] )) { 3131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng eq = False; 3132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (eq) vassert(a1->u.CCall.retty == a2->u.CCall.retty); 3137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return eq; 3138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: vpanic("eq_AvailExpr"); 3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* availExpr_to_IRExpr ( AvailExpr* ae ) 3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst* con; 3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (ae->tag) { 3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ut: 3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( ae->u.Ut.op, IRExpr_RdTmp(ae->u.Ut.arg) ); 3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btt: 3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Binop( ae->u.Btt.op, 3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Btt.arg1), 3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Btt.arg2) ); 3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btc: 3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con = LibVEX_Alloc(sizeof(IRConst)); 3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *con = ae->u.Btc.con2; 3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Binop( ae->u.Btc.op, 3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Btc.arg1), 3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Const(con) ); 3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Bct: 3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con = LibVEX_Alloc(sizeof(IRConst)); 3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *con = ae->u.Bct.con1; 3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Binop( ae->u.Bct.op, 3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Const(con), 3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Bct.arg2) ); 3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Cf64i: 3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Const(IRConst_F64i(ae->u.Cf64i.f64i)); 3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Mttt: 3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Mux0X(IRExpr_RdTmp(ae->u.Mttt.co), 3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Mttt.e0), 3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.Mttt.eX)); 3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case GetIt: 3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_GetI(ae->u.GetIt.descr, 3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.GetIt.ix), 3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.bias); 3175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case CCall: { 3176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, n = ae->u.CCall.nArgs; 3177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(n >= 0); 3178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr** vec = LibVEX_Alloc((n+1) * sizeof(IRExpr*)); 3179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vec[n] = NULL; 3180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) { 3181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConst* tc = &ae->u.CCall.args[i]; 3182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tc->tag == TCc) { 3183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vec[i] = IRExpr_Const(tc->u.con); 3184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if (tc->tag == TCt) { 3186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vec[i] = IRExpr_RdTmp(tc->u.tmp); 3187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else vpanic("availExpr_to_IRExpr:CCall-arg"); 3189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRExpr_CCall(ae->u.CCall.cee, 3191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ae->u.CCall.retty, 3192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vec); 3193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("availExpr_to_IRExpr"); 3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browninline 3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRTemp subst_AvailExpr_Temp ( HashHW* env, IRTemp tmp ) 3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HWord res; 3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* env :: IRTemp -> IRTemp */ 3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (lookupHHW( env, &res, (HWord)tmp )) 3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (IRTemp)res; 3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return tmp; 3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void subst_AvailExpr ( HashHW* env, AvailExpr* ae ) 3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* env :: IRTemp -> IRTemp */ 3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (ae->tag) { 3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ut: 3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Ut.arg = subst_AvailExpr_Temp( env, ae->u.Ut.arg ); 3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btt: 3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btt.arg1 = subst_AvailExpr_Temp( env, ae->u.Btt.arg1 ); 3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btt.arg2 = subst_AvailExpr_Temp( env, ae->u.Btt.arg2 ); 3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Btc: 3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btc.arg1 = subst_AvailExpr_Temp( env, ae->u.Btc.arg1 ); 3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Bct: 3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Bct.arg2 = subst_AvailExpr_Temp( env, ae->u.Bct.arg2 ); 3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Cf64i: 3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Mttt: 3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.co = subst_AvailExpr_Temp( env, ae->u.Mttt.co ); 3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.e0 = subst_AvailExpr_Temp( env, ae->u.Mttt.e0 ); 3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.eX = subst_AvailExpr_Temp( env, ae->u.Mttt.eX ); 3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case GetIt: 3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.ix = subst_AvailExpr_Temp( env, ae->u.GetIt.ix ); 3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case CCall: { 3238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int i, n = ae->u.CCall.nArgs;; 3239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < n; i++) { 3240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TmpOrConst* tc = &ae->u.CCall.args[i]; 3241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (tc->tag == TCt) { 3242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tc->u.tmp = subst_AvailExpr_Temp( env, tc->u.tmp ); 3243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("subst_AvailExpr"); 3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic AvailExpr* irExpr_to_AvailExpr ( IRExpr* e ) 3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AvailExpr* ae; 3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Unop 3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Unop.arg->tag == Iex_RdTmp) { 3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Ut; 3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Ut.op = e->Iex.Unop.op; 3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Ut.arg = e->Iex.Unop.arg->Iex.RdTmp.tmp; 3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Binop 3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg1->tag == Iex_RdTmp 3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg2->tag == Iex_RdTmp) { 3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Btt; 3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btt.op = e->Iex.Binop.op; 3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btt.arg1 = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btt.arg2 = e->Iex.Binop.arg2->Iex.RdTmp.tmp; 3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Binop 3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg1->tag == Iex_RdTmp 3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg2->tag == Iex_Const) { 3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Btc; 3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btc.op = e->Iex.Binop.op; 3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btc.arg1 = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Btc.con2 = *(e->Iex.Binop.arg2->Iex.Const.con); 3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Binop 3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg1->tag == Iex_Const 3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Binop.arg2->tag == Iex_RdTmp) { 3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Bct; 3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Bct.op = e->Iex.Binop.op; 3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Bct.arg2 = e->Iex.Binop.arg2->Iex.RdTmp.tmp; 3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Bct.con1 = *(e->Iex.Binop.arg1->Iex.Const.con); 3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Const 3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Const.con->tag == Ico_F64i) { 3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Cf64i; 3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Cf64i.f64i = e->Iex.Const.con->Ico.F64i; 3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_Mux0X 3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Mux0X.cond->tag == Iex_RdTmp 3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Mux0X.expr0->tag == Iex_RdTmp 3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.Mux0X.exprX->tag == Iex_RdTmp) { 3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = Mttt; 3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.co = e->Iex.Mux0X.cond->Iex.RdTmp.tmp; 3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.e0 = e->Iex.Mux0X.expr0->Iex.RdTmp.tmp; 3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.Mttt.eX = e->Iex.Mux0X.exprX->Iex.RdTmp.tmp; 3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag == Iex_GetI 3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && e->Iex.GetI.ix->tag == Iex_RdTmp) { 3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = LibVEX_Alloc(sizeof(AvailExpr)); 3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->tag = GetIt; 3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.descr = e->Iex.GetI.descr; 3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.ix = e->Iex.GetI.ix->Iex.RdTmp.tmp; 3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.bias = e->Iex.GetI.bias; 3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ae; 3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (e->tag == Iex_CCall) { 3329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ae = LibVEX_Alloc(sizeof(AvailExpr)); 3330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ae->tag = CCall; 3331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Ok to share only the cee, since it is immutable. */ 3332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ae->u.CCall.cee = e->Iex.CCall.cee; 3333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ae->u.CCall.retty = e->Iex.CCall.retty; 3334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* irExprVec_to_TmpOrConsts will assert if the args are 3335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng neither tmps nor constants, but that's ok .. that's all they 3336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng should be. */ 3337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng irExprVec_to_TmpOrConsts( 3338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &ae->u.CCall.args, &ae->u.CCall.nArgs, 3339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.CCall.args 3340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 3341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return ae; 3342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The BB is modified in-place. Returns True if any changes were 3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown made. */ 3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool do_cse_BB ( IRSB* bb ) 3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j, paranoia; 3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp t, q; 3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AvailExpr* eprime; 3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AvailExpr* ae; 3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool invalidate; 3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool anyDone = False; 3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* tenv = newHHW(); /* :: IRTemp -> IRTemp */ 3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HashHW* aenv = newHHW(); /* :: AvailExpr* -> IRTemp */ 3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(sizeof(IRTemp) <= sizeof(HWord)); 3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) { ppIRSB(bb); vex_printf("\n\n"); } 3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Iterate forwards over the stmts. 3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing "t = E", where E is one of the 5 AvailExpr forms: 3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let E' = apply tenv substitution to E 3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown search aenv for E' 3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if a mapping E' -> q is found, 3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown replace this stmt by "t = q" 3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and add binding t -> q to tenv 3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add binding E' -> t to aenv 3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown replace this stmt by "t = E'" 3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Other statements are only interesting to the extent that they 3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown might invalidate some of the expressions in aenv. So there is 3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown an invalidate-bindings check for each statement seen. 3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------ BEGIN invalidate aenv bindings ------ */ 3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is critical: remove from aenv any E' -> .. bindings 3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which might be invalidated by this statement. The only 3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vulnerable kind of bindings are the GetI kind. 3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Dirty call - dump (paranoia level -> 2) 3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Store - dump (ditto) 3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Put, PutI - dump unless no-overlap is proven (.. -> 1) 3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Uses getAliasingRelation_IC and getAliasingRelation_II 3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to do the no-overlap assessments needed for Put/PutI. 3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: case Ist_Store: case Ist_MBE: 3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: case Ist_LLSC: 3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paranoia = 2; break; 3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: case Ist_PutI: 3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paranoia = 1; break; 3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: case Ist_IMark: case Ist_AbiHint: 3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: case Ist_Exit: 3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paranoia = 0; break; 3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("do_cse_BB(1)"); 3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (paranoia > 0) { 3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < aenv->used; j++) { 3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!aenv->inuse[j]) 3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae = (AvailExpr*)aenv->key[j]; 3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ae->tag != GetIt) 3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidate = False; 3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (paranoia >= 2) { 3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidate = True; 3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(paranoia == 1); 3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Put) { 3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (getAliasingRelation_IC( 3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.descr, 3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.GetIt.ix), 3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Put.offset, 3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeOfIRExpr(bb->tyenv,st->Ist.Put.data) 3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) != NoAlias) 3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidate = True; 3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_PutI) { 3432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti = st->Ist.PutI.details; 3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (getAliasingRelation_II( 3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.descr, 3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(ae->u.GetIt.ix), 3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ae->u.GetIt.bias, 3437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->descr, 3438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->ix, 3439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->bias 3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) != NoAlias) 3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidate = True; 3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("do_cse_BB(2)"); 3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (invalidate) { 3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aenv->inuse[j] = False; 3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aenv->key[j] = (HWord)NULL; /* be sure */ 3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* for j */ 3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* paranoia > 0 */ 3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ------ ENV invalidate aenv bindings ------ */ 3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ignore not-interestings */ 3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag != Ist_WrTmp) 3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t = st->Ist.WrTmp.tmp; 3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eprime = irExpr_to_AvailExpr(st->Ist.WrTmp.data); 3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ignore if not of AvailExpr form */ 3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!eprime) 3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("considering: " ); ppIRStmt(st); vex_printf("\n"); */ 3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* apply tenv */ 3469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown subst_AvailExpr( tenv, eprime ); 3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* search aenv for eprime, unfortunately the hard way */ 3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < aenv->used; j++) 3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (aenv->inuse[j] && eq_AvailExpr(eprime, (AvailExpr*)aenv->key[j])) 3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (j < aenv->used) { 3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A binding E' -> q was found. Replace stmt by "t = q" and 3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown note the t->q binding in tenv. */ 3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* (this is the core of the CSE action) */ 3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown q = (IRTemp)aenv->val[j]; 3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_WrTmp( t, IRExpr_RdTmp(q) ); 3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToHHW( tenv, (HWord)t, (HWord)q ); 3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown anyDone = True; 3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* No binding was found, so instead we add E' -> t to our 3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown collection of available expressions, replace this stmt 3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with "t = E'", and move on. */ 3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_WrTmp( t, availExpr_to_IRExpr(eprime) ); 3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToHHW( aenv, (HWord)eprime, (HWord)t ); 3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sanityCheckIRSB(bb, Ity_I32); 3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n\n"); 3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return anyDone; 3499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Add32/Sub32 chain collapsing ---*/ 3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ----- Helper functions for Add32/Sub32 chain collapsing ----- */ 3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this expression "Add32(tmp,const)" or "Sub32(tmp,const)" ? If 3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown yes, set *tmp and *i32 appropriately. *i32 is set as if the 3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown root node is Add32, not Sub32. */ 3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool isAdd32OrSub32 ( IRExpr* e, IRTemp* tmp, Int* i32 ) 3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->tag != Iex_Binop) 3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Binop.op != Iop_Add32 && e->Iex.Binop.op != Iop_Sub32) 3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Binop.arg1->tag != Iex_RdTmp) 3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Binop.arg2->tag != Iex_Const) 3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *tmp = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *i32 = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32); 3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e->Iex.Binop.op == Iop_Sub32) 3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *i32 = -*i32; 3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Figure out if tmp can be expressed as tmp2 +32 const, for some 3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown other tmp2. Scan backwards from the specified start point -- an 3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown optimisation. */ 3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool collapseChain ( IRSB* bb, Int startHere, 3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp tmp, 3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp* tmp2, Int* i32 ) 3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int j, ii; 3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp vv; 3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* e; 3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* the (var, con) pair contain the current 'representation' for 3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'tmp'. We start with 'tmp + 0'. */ 3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp var = tmp; 3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int con = 0; 3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Scan backwards to see if tmp can be replaced by some other tmp 3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown +/- a constant. */ 3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = startHere; j >= 0; j--) { 3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[j]; 3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag != Ist_WrTmp) 3553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.WrTmp.tmp != var) 3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e = st->Ist.WrTmp.data; 3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!isAdd32OrSub32(e, &vv, &ii)) 3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown var = vv; 3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con += ii; 3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (j == -1) 3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no earlier binding for var .. ill-formed IR */ 3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("collapseChain"); 3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* so, did we find anything interesting? */ 3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (var == tmp) 3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; /* no .. */ 3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *tmp2 = var; 3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *i32 = con; 3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------- Main function for Add32/Sub32 chain collapsing ------ */ 3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void collapse_AddSub_chains_BB ( IRSB* bb ) 3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt *st; 3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp var, var2; 3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, con, con2; 3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb->stmts_used-1; i >= 0; i--) { 3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Try to collapse 't1 = Add32/Sub32(t2, con)'. */ 3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp 3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isAdd32OrSub32(st->Ist.WrTmp.data, &var, &con)) { 3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So e1 is of the form Add32(var,con) or Sub32(var,-con). 3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Find out if var can be expressed as var2 + con2. */ 3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (collapseChain(bb, i-1, var, &var2, &con2)) { 3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("replacing1 "); 3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" with "); 3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con2 += con; 3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] 3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = IRStmt_WrTmp( 3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.tmp, 3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (con2 >= 0) 3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? IRExpr_Binop(Iop_Add32, 3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(var2), 3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Const(IRConst_U32(con2))) 3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : IRExpr_Binop(Iop_Sub32, 3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(var2), 3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Const(IRConst_U32(-con2))) 3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(bb->stmts[i]); 3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Try to collapse 't1 = GetI[t2, con]'. */ 3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp 3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.WrTmp.data->tag == Iex_GetI 3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.WrTmp.data->Iex.GetI.ix->tag == Iex_RdTmp 3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && collapseChain(bb, i-1, st->Ist.WrTmp.data->Iex.GetI.ix 3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ->Iex.RdTmp.tmp, &var2, &con2)) { 3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("replacing3 "); 3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" with "); 3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con2 += st->Ist.WrTmp.data->Iex.GetI.bias; 3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] 3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = IRStmt_WrTmp( 3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.tmp, 3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_GetI(st->Ist.WrTmp.data->Iex.GetI.descr, 3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_RdTmp(var2), 3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con2)); 3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(bb->stmts[i]); 3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Perhaps st is PutI[t, con] ? */ 3650663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti = st->Ist.PutI.details; 3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_PutI 3652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && puti->ix->tag == Iex_RdTmp 3653663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && collapseChain(bb, i-1, puti->ix->Iex.RdTmp.tmp, 3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &var2, &con2)) { 3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("replacing2 "); 3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" with "); 3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng con2 += puti->bias; 3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] 3662663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = IRStmt_PutI(mkIRPutI(puti->descr, 3663663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_RdTmp(var2), 3664663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng con2, 3665663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->data)); 3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(bb->stmts[i]); 3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* for */ 3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- PutI/GetI transformations ---*/ 3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Given the parts (descr, tmp, bias) for a GetI, scan backwards from 3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the given starting point to find, if any, a PutI which writes 3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exactly the same piece of guest state, and so return the expression 3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that the PutI writes. This is the core of PutI-GetI forwarding. */ 3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRExpr* findPutI ( IRSB* bb, Int startHere, 3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descrG, IRExpr* ixG, Int biasG ) 3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int j; 3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 3692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GSAliasing relation; 3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) { 3695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\nfindPutI "); 3696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRRegArray(descrG); 3697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" "); 3698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(ixG); 3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" %d\n", biasG); 3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Scan backwards in bb from startHere to find a suitable PutI 3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binding for (descrG, ixG, biasG), if any. */ 3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = startHere; j >= 0; j--) { 3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[j]; 3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Put) { 3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Non-indexed Put. This can't give a binding, but we do 3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown need to check it doesn't invalidate the search by 3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlapping any part of the indexed guest state. */ 3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation 3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = getAliasingRelation_IC( 3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown descrG, ixG, 3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Put.offset, 3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (relation == NoAlias) { 3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* we're OK; keep going */ 3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* relation == UnknownAlias || relation == ExactAlias */ 3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If this assertion fails, we've found a Put which writes 3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown an area of guest state which is read by a GetI. Which 3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is unlikely (although not per se wrong). */ 3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(relation != ExactAlias); 3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This Put potentially writes guest state that the GetI 3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reads; we must fail. */ 3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_PutI) { 3737663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti = st->Ist.PutI.details; 3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation = getAliasingRelation_II( 3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown descrG, ixG, biasG, 3741663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->descr, 3742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->ix, 3743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->bias 3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (relation == NoAlias) { 3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This PutI definitely doesn't overlap. Ignore it and 3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown keep going. */ 3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; /* the for j loop */ 3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (relation == UnknownAlias) { 3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We don't know if this PutI writes to the same guest 3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown state that the GetI, or not. So we have to give up. */ 3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Otherwise, we've found what we're looking for. */ 3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(relation == ExactAlias); 3760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return puti->data; 3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* if (st->tag == Ist_PutI) */ 3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Dirty) { 3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Be conservative. If the dirty call has any guest effects at 3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown all, give up. We could do better -- only give up if there 3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are any guest writes/modifies. */ 3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.Dirty.details->nFxState > 0) 3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* for */ 3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* No valid replacement was found. */ 3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Assuming pi is a PutI stmt, is s2 identical to it (in the sense 3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that it writes exactly the same piece of guest state) ? Safe 3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown answer: False. */ 3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool identicalPutIs ( IRStmt* pi, IRStmt* s2 ) 3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(pi->tag == Ist_PutI); 3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s2->tag != Ist_PutI) 3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *p1 = pi->Ist.PutI.details; 3791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *p2 = s2->Ist.PutI.details; 3792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return toBool( 3794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getAliasingRelation_II( 3795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p1->descr, p1->ix, p1->bias, 3796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p2->descr, p2->ix, p2->bias 3797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 3798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == ExactAlias 3799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Assuming pi is a PutI stmt, is s2 a Get/GetI/Put/PutI which might 3804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown overlap it? Safe answer: True. Note, we could do a lot better 3805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown than this if needed. */ 3806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool guestAccessWhichMightOverlapPutI ( 3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTypeEnv* tyenv, IRStmt* pi, IRStmt* s2 3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GSAliasing relation; 3813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt minoffP, maxoffP; 3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(pi->tag == Ist_PutI); 3816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *p1 = pi->Ist.PutI.details; 3818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng getArrayBounds(p1->descr, &minoffP, &maxoffP); 3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (s2->tag) { 3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* just be paranoid ... these should be rare. */ 3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is unbelievably lame, but it's probably not 3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown significant from a performance point of view. Really, a 3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CAS is a load-store op, so it should be safe to say False. 3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown However .. */ 3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the dirty call has any guest effects at all, give up. 3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Probably could do better. */ 3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s2->Ist.Dirty.details->nFxState > 0) 3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(s2->Ist.Put.data)); 3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation 3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = getAliasingRelation_IC( 3849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p1->descr, p1->ix, 3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.Put.offset, 3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeOfIRExpr(tyenv,s2->Ist.Put.data) 3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto have_relation; 3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_PutI: { 3856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *p2 = s2->Ist.PutI.details; 3857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(p2->ix)); 3859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert(isIRAtom(p2->data)); 3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation 3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = getAliasingRelation_II( 3862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p1->descr, p1->ix, p1->bias, 3863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p2->descr, p2->ix, p2->bias 3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto have_relation; 3866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s2->Ist.WrTmp.data->tag == Iex_GetI) { 3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation 3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = getAliasingRelation_II( 3872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p1->descr, p1->ix, p1->bias, 3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.WrTmp.data->Iex.GetI.descr, 3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.WrTmp.data->Iex.GetI.ix, 3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.WrTmp.data->Iex.GetI.bias 3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto have_relation; 3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s2->Ist.WrTmp.data->tag == Iex_Get) { 3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relation 3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = getAliasingRelation_IC( 3882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng p1->descr, p1->ix, 3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.WrTmp.data->Iex.Get.offset, 3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s2->Ist.WrTmp.data->Iex.Get.ty 3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto have_relation; 3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(s2->Ist.Store.addr)); 3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(s2->Ist.Store.data)); 3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRStmt(s2); vex_printf("\n"); 3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("guestAccessWhichMightOverlapPutI"); 3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_relation: 3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (relation == NoAlias) 3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; /* ExactAlias or UnknownAlias */ 3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------- PutI/GetI transformations main functions --------- */ 3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove redundant GetIs, to the extent that they can be detected. 3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb is modified in-place. */ 3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_redundant_GetI_elimination ( IRSB* bb ) 3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb->stmts_used-1; i >= 0; i--) { 3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp 3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.WrTmp.data->tag == Iex_GetI 3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && st->Ist.WrTmp.data->Iex.GetI.ix->tag == Iex_RdTmp) { 3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRRegArray* descr = st->Ist.WrTmp.data->Iex.GetI.descr; 3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* ix = st->Ist.WrTmp.data->Iex.GetI.ix; 3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int bias = st->Ist.WrTmp.data->Iex.GetI.bias; 3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* replacement = findPutI(bb, i-1, descr, ix, bias); 3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (replacement 3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && isIRAtom(replacement) 3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make sure we're doing a type-safe transformation! */ 3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && typeOfIRExpr(bb->tyenv, replacement) == descr->elemTy) { 3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("rGI: "); 3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(st->Ist.WrTmp.data); 3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" -> "); 3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(replacement); 3941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_WrTmp(st->Ist.WrTmp.tmp, replacement); 3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove redundant PutIs, to the extent which they can be detected. 3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb is modified in-place. */ 3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_redundant_PutI_elimination ( IRSB* bb ) 3956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j; 3958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool delete; 3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt *st, *stj; 3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vassert 3962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess 3963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess); 3964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 3966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag != Ist_PutI) 3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ok, search forwards from here to see if we can find another 3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PutI which makes this one redundant, and dodging various 3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hazards. Search forwards: 3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If conditional exit, give up (because anything after that 3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does not postdominate this put). 3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If a Get which might overlap, give up (because this PutI 3975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not necessarily dead). 3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If a Put which is identical, stop with success. 3977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If a Put which might overlap, but is not identical, give up. 3978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If a dirty helper call which might write guest state, give up. 3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If a Put which definitely doesn't overlap, or any other 3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown kind of stmt, continue. 3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete = False; 3983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i+1; j < bb->stmts_used; j++) { 3984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stj = bb->stmts[j]; 3985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (stj->tag == Ist_NoOp) 3986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (identicalPutIs(st, stj)) { 3988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* success! */ 3989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete = True; 3990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (stj->tag == Ist_Exit) 3993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* give up */ 3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_Dirty) 3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* give up; could do better here */ 3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (guestAccessWhichMightOverlapPutI(bb->tyenv, st, stj)) 3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* give up */ 4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (delete) { 4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("rPI: "); 4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[i] = IRStmt_NoOp(); 4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Loop unrolling ---*/ 4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Adjust all tmp values (names) in e by delta. e is destructively 4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified. */ 4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void deltaIRExpr ( IRExpr* e, Int delta ) 4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.RdTmp.tmp += delta; 4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.GetI.ix, delta); 4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Qop: 4037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Qop.details->arg1, delta); 4038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Qop.details->arg2, delta); 4039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Qop.details->arg3, delta); 4040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Qop.details->arg4, delta); 4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Triop: 4043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Triop.details->arg1, delta); 4044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Triop.details->arg2, delta); 4045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(e->Iex.Triop.details->arg3, delta); 4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Binop.arg1, delta); 4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Binop.arg2, delta); 4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Unop.arg, delta); 4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Load.addr, delta); 4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; e->Iex.CCall.args[i]; i++) 4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.CCall.args[i], delta); 4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Mux0X.cond, delta); 4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Mux0X.expr0, delta); 4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(e->Iex.Mux0X.exprX, delta); 4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("deltaIRExpr"); 4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Adjust all tmp values (names) in st by delta. st is destructively 4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified. */ 4074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void deltaIRStmt ( IRStmt* st, Int delta ) 4076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d; 4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 4082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.AbiHint.base, delta); 4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.AbiHint.nia, delta); 4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.Put.data, delta); 4090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 4092663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(st->Ist.PutI.details->ix, delta); 4093663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng deltaIRExpr(st->Ist.PutI.details->data, delta); 4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.tmp += delta; 4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.WrTmp.data, delta); 4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.Exit.guard, delta); 4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.Store.addr, delta); 4104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.Store.data, delta); 4105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 4107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.CAS.details->oldHi != IRTemp_INVALID) 4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.CAS.details->oldHi += delta; 4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.CAS.details->oldLo += delta; 4110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.CAS.details->addr, delta); 4111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.CAS.details->expdHi) 4112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.CAS.details->expdHi, delta); 4113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.CAS.details->expdLo, delta); 4114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.CAS.details->dataHi) 4115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.CAS.details->dataHi, delta); 4116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.CAS.details->dataLo, delta); 4117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.result += delta; 4120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.LLSC.addr, delta); 4121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.LLSC.storedata) 4122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(st->Ist.LLSC.storedata, delta); 4123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 4125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 4126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(d->guard, delta); 4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d->args[i]; i++) 4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(d->args[i], delta); 4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->tmp != IRTemp_INVALID) 4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d->tmp += delta; 4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->mAddr) 4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRExpr(d->mAddr, delta); 4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("deltaIRStmt"); 4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If possible, return a loop-unrolled version of bb0. The original 4142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is changed. If not possible, return NULL. */ 4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The two schemas considered are: 4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X: BODY; goto X 4147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which unrolls to (eg) X: BODY;BODY; goto X 4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and 4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X: BODY; if (c) goto X; goto Y 4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which trivially transforms to 4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X: BODY; if (!c) goto Y; goto X; 4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown so it falls in the scope of the first case. 4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X and Y must be literal (guest) addresses. 4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int calc_unroll_factor( IRSB* bb ) 4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_stmts, i; 4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_stmts = 0; 4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb->stmts[i]->tag != Ist_NoOp) 4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_stmts++; 4168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n_stmts <= vex_control.iropt_unroll_thresh/8) { 4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) 4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex iropt: 8 x unrolling (%d sts -> %d sts)\n", 4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_stmts, 8* n_stmts); 4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 8; 4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n_stmts <= vex_control.iropt_unroll_thresh/4) { 4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) 4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex iropt: 4 x unrolling (%d sts -> %d sts)\n", 4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_stmts, 4* n_stmts); 4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 4; 4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n_stmts <= vex_control.iropt_unroll_thresh/2) { 4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) 4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex iropt: 2 x unrolling (%d sts -> %d sts)\n", 4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_stmts, 2* n_stmts); 4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 2; 4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_verbosity > 0) 4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("vex iropt: not unrolling (%d sts)\n", n_stmts); 4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRSB* maybe_loop_unroll_BB ( IRSB* bb0, Addr64 my_addr ) 4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j, jmax, n_vars; 4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool xxx_known; 4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr64 xxx_value, yyy_value; 4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* udst; 4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRConst* con; 4205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB *bb1, *bb2; 4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int unroll_factor; 4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_unroll_thresh <= 0) 4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First off, figure out if we can unroll this loop. Do this 4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without modifying bb0. */ 4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb0->jumpkind != Ijk_Boring) 4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xxx_known = False; 4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xxx_value = 0; 4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Extract the next-guest address. If it isn't a literal, we 4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have to give up. */ 4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst = bb0->next; 4224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (udst->tag == Iex_Const 4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (udst->Iex.Const.con->tag == Ico_U32 4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || udst->Iex.Const.con->tag == Ico_U64)) { 4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The BB ends in a jump to a literal location. */ 4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xxx_known = True; 4229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xxx_value = udst->Iex.Const.con->tag == Ico_U64 4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? udst->Iex.Const.con->Ico.U64 4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : (Addr64)(udst->Iex.Const.con->Ico.U32); 4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!xxx_known) 4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now we know the BB ends to a jump to a literal location. If 4238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it's a jump to itself (viz, idiom #1), move directly to the 4239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unrolling stage, first cloning the bb so the original isn't 4240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified. */ 4241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xxx_value == my_addr) { 4242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unroll_factor = calc_unroll_factor( bb0 ); 4243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (unroll_factor < 2) 4244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb1 = deepCopyIRSB( bb0 ); 4246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb0 = NULL; 4247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst = NULL; /* is now invalid */ 4248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto do_unroll; 4249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Search for the second idiomatic form: 4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown X: BODY; if (c) goto X; goto Y 4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We know Y, but need to establish that the last stmt 4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is 'if (c) goto X'. 4255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown yyy_value = xxx_value; 4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb0->stmts_used-1; i >= 0; i--) 4258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb0->stmts[i]) 4259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (i < 0) 4262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; /* block with no stmts. Strange. */ 4263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb0->stmts[i]; 4265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag != Ist_Exit) 4266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.Exit.jk != Ijk_Boring) 4268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con = st->Ist.Exit.dst; 4271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(con->tag == Ico_U32 || con->tag == Ico_U64); 4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xxx_value = con->tag == Ico_U64 4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? st->Ist.Exit.dst->Ico.U64 4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : (Addr64)(st->Ist.Exit.dst->Ico.U32); 4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If this assertion fails, we have some kind of type error. */ 4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(con->tag == udst->Iex.Const.con->tag); 4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xxx_value != my_addr) 4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We didn't find either idiom. Give up. */ 4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ok, we found idiom #2. Copy the BB, switch around the xxx and 4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown yyy values (which makes it look like idiom #1), and go into 4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unrolling proper. This means finding (again) the last stmt, in 4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the copied BB. */ 4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unroll_factor = calc_unroll_factor( bb0 ); 4290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (unroll_factor < 2) 4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb1 = deepCopyIRSB( bb0 ); 4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb0 = NULL; 4295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst = NULL; /* is now invalid */ 4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = bb1->stmts_used-1; i >= 0; i--) 4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb1->stmts[i]) 4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The next bunch of assertions should be true since we already 4301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown found and checked the last stmt in the original bb. */ 4302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(i >= 0); 4304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb1->stmts[i]; 4306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(st->tag == Ist_Exit); 4307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con = st->Ist.Exit.dst; 4309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(con->tag == Ico_U32 || con->tag == Ico_U64); 4310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst = bb1->next; 4312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(udst->tag == Iex_Const); 4313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(udst->Iex.Const.con->tag == Ico_U32 4314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || udst->Iex.Const.con->tag == Ico_U64); 4315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(con->tag == udst->Iex.Const.con->tag); 4316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* switch the xxx and yyy fields around */ 4318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (con->tag == Ico_U64) { 4319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst->Iex.Const.con->Ico.U64 = xxx_value; 4320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con->Ico.U64 = yyy_value; 4321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown udst->Iex.Const.con->Ico.U32 = (UInt)xxx_value; 4323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown con->Ico.U32 = (UInt)yyy_value; 4324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* negate the test condition */ 4327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Exit.guard 4328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = IRExpr_Unop(Iop_Not1,deepCopyIRExpr(st->Ist.Exit.guard)); 4329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- The unroller proper. Both idioms are by now --- */ 4331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- now converted to idiom 1. --- */ 4332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_unroll: 4334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(unroll_factor == 2 4336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || unroll_factor == 4 4337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || unroll_factor == 8); 4338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jmax = unroll_factor==8 ? 3 : (unroll_factor==4 ? 2 : 1); 4340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 1; j <= jmax; j++) { 4341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_vars = bb1->tyenv->types_used; 4343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb2 = deepCopyIRSB(bb1); 4345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n_vars; i++) 4346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)newIRTemp(bb1->tyenv, bb2->tyenv->types[i]); 4347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb2->stmts_used; i++) { 4349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* deltaIRStmt destructively modifies the stmt, but 4350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that's OK since bb2 is a complete fresh copy of bb1. */ 4351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deltaIRStmt(bb2->stmts[i], n_vars); 4352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addStmtToIRSB(bb1, bb2->stmts[i]); 4353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) { 4357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\nUNROLLED (%llx)\n", my_addr); 4358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb1); 4359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 4360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Flattening; sigh. The unroller succeeds in breaking flatness 4363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by negating the test condition. This should be fixed properly. 4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown For the moment use this shotgun approach. */ 4365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return flatten_BB(bb1); 4366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 4370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The tree builder ---*/ 4371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 4372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This isn't part of IR optimisation. Really it's a pass done prior 4374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to instruction selection, which improves the code that the 4375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instruction selector can produce. */ 4376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- The 'tmp' environment is the central data structure here --- */ 4378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The number of outstanding bindings we're prepared to track. 4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The number of times the env becomes full and we have to dump 4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the oldest binding (hence reducing code quality) falls very 4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rapidly as the env size increases. 8 gives reasonable performance 4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown under most circumstances. */ 4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define A_NENV 10 4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* bindee == NULL === slot is not in use 4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bindee != NULL === slot is in use 4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 4390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRTemp binder; 4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* bindee; 4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool doesLoad; 4394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool doesGet; 4395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ATmpInfo; 4397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((unused)) 4399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void ppAEnv ( ATmpInfo* env ) 4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < A_NENV; i++) { 4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("%d tmp %d val ", i, (Int)env[i].binder); 4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[i].bindee) 4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRExpr(env[i].bindee); 4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("(null)"); 4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); 4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- Tree-traversal fns --- */ 4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Traverse an expr, and detect if any part of it reads memory or does 4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a Get. Be careful ... this really controls how much the 4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tree-builder can reorder the code, so getting it right is critical. 4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void setHints_Expr (Bool* doesLoad, Bool* doesGet, IRExpr* e ) 4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; e->Iex.CCall.args[i]; i++) 4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.CCall.args[i]); 4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Mux0X.cond); 4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Mux0X.expr0); 4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Mux0X.exprX); 4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Qop: 4432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Qop.details->arg1); 4433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Qop.details->arg2); 4434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Qop.details->arg3); 4435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Qop.details->arg4); 4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Triop: 4438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg1); 4439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg2); 4440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng setHints_Expr(doesLoad, doesGet, e->Iex.Triop.details->arg3); 4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Binop.arg1); 4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Binop.arg2); 4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Unop.arg); 4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *doesLoad = True; 4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.Load.addr); 4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *doesGet = True; 4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *doesGet = True; 4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(doesLoad, doesGet, e->Iex.GetI.ix); 4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("setHints_Expr"); 4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a binding to the front of the env and slide all the rest 4471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown backwards. It should be the case that the last slot is free. */ 4472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void addToEnvFront ( ATmpInfo* env, IRTemp binder, IRExpr* bindee ) 4473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(env[A_NENV-1].bindee == NULL); 4476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = A_NENV-1; i >= 1; i--) 4477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[i] = env[i-1]; 4478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[0].binder = binder; 4479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[0].bindee = bindee; 4480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[0].doesLoad = False; /* filled in later */ 4481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[0].doesGet = False; /* filled in later */ 4482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Given uses :: array of UShort, indexed by IRTemp 4485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Add the use-occurrences of temps in this expression 4486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to the env. 4487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void aoccCount_Expr ( UShort* uses, IRExpr* e ) 4489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 4493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: /* the only interesting case */ 4495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uses[e->Iex.RdTmp.tmp]++; 4496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 4499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Mux0X.cond); 4500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Mux0X.expr0); 4501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Mux0X.exprX); 4502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Qop: 4505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Qop.details->arg1); 4506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Qop.details->arg2); 4507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Qop.details->arg3); 4508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Qop.details->arg4); 4509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Triop: 4512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Triop.details->arg1); 4513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Triop.details->arg2); 4514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, e->Iex.Triop.details->arg3); 4515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 4518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Binop.arg1); 4519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Binop.arg2); 4520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 4523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Unop.arg); 4524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 4527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.Load.addr); 4528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 4531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; e->Iex.CCall.args[i]; i++) 4532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.CCall.args[i]); 4533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 4536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, e->Iex.GetI.ix); 4537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 4540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 4541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 4545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("aoccCount_Expr"); 4546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Given uses :: array of UShort, indexed by IRTemp 4551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Add the use-occurrences of temps in this statement 4552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to the env. 4553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void aoccCount_Stmt ( UShort* uses, IRStmt* st ) 4555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d; 4558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS* cas; 4559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 4560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 4561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.AbiHint.base); 4562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.AbiHint.nia); 4563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 4565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.WrTmp.data); 4566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 4568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.Put.data); 4569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 4571663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, st->Ist.PutI.details->ix); 4572663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aoccCount_Expr(uses, st->Ist.PutI.details->data); 4573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 4575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.Store.addr); 4576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.Store.data); 4577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 4579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 4580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, cas->addr); 4581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cas->expdHi) 4582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, cas->expdHi); 4583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, cas->expdLo); 4584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cas->dataHi) 4585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, cas->dataHi); 4586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, cas->dataLo); 4587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 4589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.LLSC.addr); 4590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.LLSC.storedata) 4591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.LLSC.storedata); 4592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 4594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 4595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->mFx != Ifx_None) 4596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, d->mAddr); 4597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, d->guard); 4598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d->args[i]; i++) 4599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, d->args[i]); 4600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 4602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 4603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 4604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 4606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, st->Ist.Exit.guard); 4607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 4608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 4610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("aoccCount_Stmt"); 4611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Look up a binding for tmp in the env. If found, return the bound 4615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expression, and set the env's binding to NULL so it is marked as 4616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used. If not found, return NULL. */ 4617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* atbSubst_Temp ( ATmpInfo* env, IRTemp tmp ) 4619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < A_NENV; i++) { 4622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[i].binder == tmp && env[i].bindee != NULL) { 4623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* bindee = env[i].bindee; 4624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[i].bindee = NULL; 4625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bindee; 4626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 4629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Traverse e, looking for temps. For each observed temp, see if env 4632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown contains a binding for the temp, and if so return the bound value. 4633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The env has the property that any binding it holds is 4634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'single-shot', so once a binding is used, it is marked as no longer 4635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown available, by setting its .bindee field to NULL. */ 4636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool is_Unop ( IRExpr* e, IROp op ) { 4638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e->tag == Iex_Unop && e->Iex.Unop.op == op; 4639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool is_Binop ( IRExpr* e, IROp op ) { 4641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e->tag == Iex_Binop && e->Iex.Binop.op == op; 4642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* fold_IRExpr_Binop ( IROp op, IRExpr* a1, IRExpr* a2 ) 4645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 4647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Or32: 4648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Or32( CmpwNEZ32(x), CmpwNEZ32(y) ) --> CmpwNEZ32( Or32( x, y ) ) */ 4649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(a1, Iop_CmpwNEZ32) && is_Unop(a2, Iop_CmpwNEZ32)) 4650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_CmpwNEZ32, 4651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Binop( Iop_Or32, a1->Iex.Unop.arg, 4652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a2->Iex.Unop.arg ) ); 4653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpNE32: 4656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Since X has type Ity_I1 we can simplify: 4657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov CmpNE32(1Uto32(X),0)) ==> X */ 4658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_Unop(a1, Iop_1Uto32) && isZeroU32(a2)) 4659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return a1->Iex.Unop.arg; 4660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 4661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no reduction rule applies */ 4666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Binop( op, a1, a2 ); 4667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* fold_IRExpr_Unop ( IROp op, IRExpr* aa ) 4670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 4672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpwNEZ64: 4673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CmpwNEZ64( Or64 ( CmpwNEZ64(x), y ) ) --> CmpwNEZ64( Or64( x, y ) ) */ 4674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Binop(aa, Iop_Or64) 4675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && is_Unop(aa->Iex.Binop.arg1, Iop_CmpwNEZ64)) 4676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fold_IRExpr_Unop( 4677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpwNEZ64, 4678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Binop(Iop_Or64, 4679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aa->Iex.Binop.arg1->Iex.Unop.arg, 4680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aa->Iex.Binop.arg2)); 4681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CmpwNEZ64( Or64 ( x, CmpwNEZ64(y) ) ) --> CmpwNEZ64( Or64( x, y ) ) */ 4682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Binop(aa, Iop_Or64) 4683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && is_Unop(aa->Iex.Binop.arg2, Iop_CmpwNEZ64)) 4684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fold_IRExpr_Unop( 4685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpwNEZ64, 4686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr_Binop(Iop_Or64, 4687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aa->Iex.Binop.arg1, 4688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aa->Iex.Binop.arg2->Iex.Unop.arg)); 4689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNEZ64: 4691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CmpNEZ64( Left64(x) ) --> CmpNEZ64(x) */ 4692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_Left64)) 4693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop(Iop_CmpNEZ64, aa->Iex.Unop.arg); 4694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpwNEZ32: 4696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CmpwNEZ32( CmpwNEZ32 ( x ) ) --> CmpwNEZ32 ( x ) */ 4697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_CmpwNEZ32)) 4698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_CmpwNEZ32, aa->Iex.Unop.arg ); 4699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_CmpNEZ32: 4701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CmpNEZ32( Left32(x) ) --> CmpNEZ32(x) */ 4702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_Left32)) 4703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop(Iop_CmpNEZ32, aa->Iex.Unop.arg); 4704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* CmpNEZ32( 1Uto32(X) ) --> X */ 4705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_Unop(aa, Iop_1Uto32)) 4706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return aa->Iex.Unop.arg; 4707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 4708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case Iop_CmpNEZ8: 4709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* CmpNEZ8( 1Uto8(X) ) --> X */ 4710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_Unop(aa, Iop_1Uto8)) 4711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return aa->Iex.Unop.arg; 4712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_Left32: 4714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Left32( Left32(x) ) --> Left32(x) */ 4715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_Left32)) 4716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_Left32, aa->Iex.Unop.arg ); 4717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32to1: 4719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32to1( 1Uto32 ( x ) ) --> x */ 4720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_1Uto32)) 4721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return aa->Iex.Unop.arg; 4722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32to1( CmpwNEZ32 ( x )) --> CmpNEZ32(x) */ 4723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_CmpwNEZ32)) 4724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_CmpNEZ32, aa->Iex.Unop.arg ); 4725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to1: 4727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64to1( 1Uto64 ( x ) ) --> x */ 4728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_1Uto64)) 4729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return aa->Iex.Unop.arg; 4730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64to1( CmpwNEZ64 ( x )) --> CmpNEZ64(x) */ 4731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_CmpwNEZ64)) 4732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_CmpNEZ64, aa->Iex.Unop.arg ); 4733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_64to32: 4735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64to32( 32Uto64 ( x )) --> x */ 4736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_32Uto64)) 4737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return aa->Iex.Unop.arg; 4738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 64to32( 8Uto64 ( x )) --> 8Uto32(x) */ 4739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_8Uto64)) 4740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop(Iop_8Uto32, aa->Iex.Unop.arg); 4741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_32Uto64: 4744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32Uto64( 8Uto32( x )) --> 8Uto64(x) */ 4745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_8Uto32)) 4746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop(Iop_8Uto64, aa->Iex.Unop.arg); 4747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 32Uto64( 16Uto32( x )) --> 16Uto64(x) */ 4748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_16Uto32)) 4749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop(Iop_16Uto64, aa->Iex.Unop.arg); 4750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32Uto64(64to32( Shr64( 32Uto64(64to32(x)), sh )) 4751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng --> Shr64( 32Uto64(64to32(x)), sh )) */ 4752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (is_Unop(aa, Iop_64to32) 4753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Binop(aa->Iex.Unop.arg, Iop_Shr64) 4754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1, Iop_32Uto64) 4755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg, 4756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_64to32)) { 4757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return aa->Iex.Unop.arg; 4758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 32Uto64(64to32( Shl64( 32Uto64(64to32(x)), sh )) 4760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng --> 32Uto64(64to32( Shl64( x, sh )) */ 4761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (is_Unop(aa, Iop_64to32) 4762663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Binop(aa->Iex.Unop.arg, Iop_Shl64) 4763663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1, Iop_32Uto64) 4764663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg, 4765663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_64to32)) { 4766663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 4767663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Unop( 4768663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_32Uto64, 4769663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Unop( 4770663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_64to32, 4771663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRExpr_Binop( 4772663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Iop_Shl64, 4773663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg->Iex.Unop.arg, 4774663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng aa->Iex.Unop.arg->Iex.Binop.arg2 4775663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ))); 4776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iop_1Sto32: 4780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 1Sto32( CmpNEZ8( 32to8( 1Uto32( CmpNEZ32( x ))))) -> CmpwNEZ32(x) */ 4781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_Unop(aa, Iop_CmpNEZ8) 4782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && is_Unop(aa->Iex.Unop.arg, Iop_32to8) 4783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && is_Unop(aa->Iex.Unop.arg->Iex.Unop.arg, Iop_1Uto32) 4784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && is_Unop(aa->Iex.Unop.arg->Iex.Unop.arg->Iex.Unop.arg, 4785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Iop_CmpNEZ32)) { 4786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( Iop_CmpwNEZ32, 4787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aa->Iex.Unop.arg->Iex.Unop.arg 4788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ->Iex.Unop.arg->Iex.Unop.arg); 4789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no reduction rule applies */ 4796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Unop( op, aa ); 4797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRExpr* atbSubst_Expr ( ATmpInfo* env, IRExpr* e ) 4800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* e2; 4802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr** args2; 4803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (e->tag) { 4806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_CCall: 4808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args2 = shallowCopyIRExprVec(e->Iex.CCall.args); 4809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; args2[i]; i++) 4810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args2[i] = atbSubst_Expr(env,args2[i]); 4811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_CCall( 4812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.CCall.cee, 4813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.CCall.retty, 4814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args2 4815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_RdTmp: 4817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = atbSubst_Temp(env, e->Iex.RdTmp.tmp); 4818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e2 ? e2 : e; 4819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Mux0X: 4820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Mux0X( 4821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Mux0X.cond), 4822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Mux0X.expr0), 4823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Mux0X.exprX) 4824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Qop: 4826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Qop( 4827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Qop.details->op, 4828663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Qop.details->arg1), 4829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Qop.details->arg2), 4830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Qop.details->arg3), 4831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Qop.details->arg4) 4832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Triop: 4834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Triop( 4835663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng e->Iex.Triop.details->op, 4836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Triop.details->arg1), 4837663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Triop.details->arg2), 4838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, e->Iex.Triop.details->arg3) 4839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Binop: 4841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fold_IRExpr_Binop( 4842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Binop.op, 4843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Binop.arg1), 4844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Binop.arg2) 4845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Unop: 4847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fold_IRExpr_Unop( 4848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Unop.op, 4849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Unop.arg) 4850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Load: 4852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_Load( 4853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Load.end, 4854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.Load.ty, 4855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.Load.addr) 4856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_GetI: 4858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRExpr_GetI( 4859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.GetI.descr, 4860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, e->Iex.GetI.ix), 4861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e->Iex.GetI.bias 4862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Const: 4864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Iex_Get: 4865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return e; 4866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 4868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("atbSubst_Expr"); 4869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Same deal as atbSubst_Expr, except for stmts. */ 4873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic IRStmt* atbSubst_Stmt ( ATmpInfo* env, IRStmt* st ) 4875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 4877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty *d, *d2; 4878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS *cas, *cas2; 4879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng IRPutI *puti, *puti2; 4880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 4882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 4883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_AbiHint( 4884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.AbiHint.base), 4885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.AbiHint.len, 4886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.AbiHint.nia) 4887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 4889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Store( 4890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Store.end, 4891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.Store.addr), 4892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.Store.data) 4893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 4895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_WrTmp( 4896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.WrTmp.tmp, 4897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.WrTmp.data) 4898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 4900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Put( 4901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Put.offset, 4902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.Put.data) 4903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 4905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti = st->Ist.PutI.details; 4906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti2 = mkIRPutI(puti->descr, 4907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, puti->ix), 4908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng puti->bias, 4909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng atbSubst_Expr(env, puti->data)); 4910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return IRStmt_PutI(puti2); 4911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 4913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Exit( 4914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.Exit.guard), 4915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.Exit.jk, 4916663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->Ist.Exit.dst, 4917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng st->Ist.Exit.offsIP 4918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 4920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return IRStmt_IMark(st->Ist.IMark.addr, 4921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov st->Ist.IMark.len, 4922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov st->Ist.IMark.delta); 4923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 4924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_NoOp(); 4925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 4926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_MBE(st->Ist.MBE.event); 4927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 4928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 4929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas2 = mkIRCAS( 4930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas->oldHi, cas->oldLo, cas->end, 4931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, cas->addr), 4932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas->expdHi ? atbSubst_Expr(env, cas->expdHi) : NULL, 4933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, cas->expdLo), 4934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas->dataHi ? atbSubst_Expr(env, cas->dataHi) : NULL, 4935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, cas->dataLo) 4936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_CAS(cas2); 4938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 4939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_LLSC( 4940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.end, 4941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.result, 4942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atbSubst_Expr(env, st->Ist.LLSC.addr), 4943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st->Ist.LLSC.storedata 4944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? atbSubst_Expr(env, st->Ist.LLSC.storedata) : NULL 4945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 4947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 4948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2 = emptyIRDirty(); 4949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *d2 = *d; 4950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d2->mFx != Ifx_None) 4951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->mAddr = atbSubst_Expr(env, d2->mAddr); 4952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->guard = atbSubst_Expr(env, d2->guard); 4953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; d2->args[i]; i++) 4954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d2->args[i] = atbSubst_Expr(env, d2->args[i]); 4955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return IRStmt_Dirty(d2); 4956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 4957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 4958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("atbSubst_Stmt"); 4959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* notstatic */ Addr64 ado_treebuild_BB ( IRSB* bb ) 4963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j, k, m; 4965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool stmtPuts, stmtStores, invalidateMe; 4966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 4967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st2; 4968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ATmpInfo env[A_NENV]; 4969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool max_ga_known = False; 4971663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr64 max_ga = 0; 4972663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_tmps = bb->tyenv->types_used; 4974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort* uses = LibVEX_Alloc(n_tmps * sizeof(UShort)); 4975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Phase 1. Scan forwards in bb, counting use occurrences of each 4977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng temp. Also count occurrences in the bb->next field. Take the 4978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng opportunity to also find the maximum guest address in the block, 4979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng since that will be needed later for deciding when we can safely 4980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng elide event checks. */ 4981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n_tmps; i++) 4983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uses[i] = 0; 4984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 4986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 4987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (st->tag) { 4988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_NoOp: 4989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng continue; 4990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ist_IMark: { 4991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int len = st->Ist.IMark.len; 4992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr64 mga = st->Ist.IMark.addr + (len < 1 ? 1 : len) - 1; 4993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng max_ga_known = True; 4994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (mga > max_ga) 4995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng max_ga = mga; 4996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 4999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 5000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 5001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Stmt( uses, st ); 5002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown aoccCount_Expr(uses, bb->next ); 5004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if 0 5006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n_tmps; i++) { 5007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (uses[i] == 0) 5008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 5009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRTemp( (IRTemp)i ); 5010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf(" used %d\n", (Int)uses[i] ); 5011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 5013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Phase 2. Scan forwards in bb. For each statement in turn: 5015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If the env is full, emit the end element. This guarantees 5017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there is at least one free slot in the following. 5018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing 't = E', occ(t)==1, 5020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let E'=env(E) 5021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete this stmt 5022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add t -> E' to the front of the env 5023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Examine E' and set the hints for E' appropriately 5024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (doesLoad? doesGet?) 5025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On seeing any other stmt, 5027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let stmt' = env(stmt) 5028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown remove from env any 't=E' binds invalidated by stmt 5029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit the invalidated stmts 5030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit stmt' 5031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown compact any holes in env 5032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by sliding entries towards the front 5033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Finally, apply env to bb->next. 5035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 5036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < A_NENV; i++) { 5038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[i].bindee = NULL; 5039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[i].binder = IRTemp_INVALID; 5040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The stmts in bb are being reordered, and we are guaranteed to 5043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end up with no more than the number we started with. Use i to 5044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be the cursor of the current stmt examined and j <= i to be that 5045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for the current stmt being written. 5046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 5047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j = 0; 5048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 5049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 5051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_NoOp) 5052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 5053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ensure there's at least one space in the env, by emitting 5055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the oldest binding if necessary. */ 5056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[A_NENV-1].bindee != NULL) { 5057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[j] = IRStmt_WrTmp( env[A_NENV-1].binder, 5058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[A_NENV-1].bindee ); 5059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j++; 5060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(j <= i); 5061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[A_NENV-1].bindee = NULL; 5062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Consider current stmt. */ 5065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->tag == Ist_WrTmp && uses[st->Ist.WrTmp.tmp] <= 1) { 5066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr *e, *e2; 5067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* optional extra: dump dead bindings as we find them. 5069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Removes the need for a prior dead-code removal pass. */ 5070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (uses[st->Ist.WrTmp.tmp] == 0) { 5071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) vex_printf("DEAD binding\n"); 5072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; /* for (i = 0; i < bb->stmts_used; i++) loop */ 5073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(uses[st->Ist.WrTmp.tmp] == 1); 5075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ok, we have 't = E', occ(t)==1. Do the abovementioned 5077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown actions. */ 5078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e = st->Ist.WrTmp.data; 5079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2 = atbSubst_Expr(env, e); 5080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addToEnvFront(env, st->Ist.WrTmp.tmp, e2); 5081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setHints_Expr(&env[0].doesLoad, &env[0].doesGet, e2); 5082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* don't advance j, as we are deleting this stmt and instead 5083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown holding it temporarily in the env. */ 5084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; /* for (i = 0; i < bb->stmts_used; i++) loop */ 5085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* we get here for any other kind of statement. */ 5088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 'use up' any bindings required by the current statement. */ 5089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st2 = atbSubst_Stmt(env, st); 5090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now, before this stmt, dump any bindings in env that it 5092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidates. These need to be dumped in the order in which 5093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown they originally entered env -- that means from oldest to 5094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown youngest. */ 5095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* stmtPuts/stmtStores characterise what the stmt under 5097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown consideration does, or might do (sidely safe @ True). */ 5098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stmtPuts 5099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toBool( st->tag == Ist_Put 5100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->tag == Ist_PutI 5101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->tag == Ist_Dirty ); 5102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* be True if this stmt writes memory or might do (==> we don't 5104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown want to reorder other loads or stores relative to it). Also, 5105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown both LL and SC fall under this classification, since we 5106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown really ought to be conservative and not reorder any other 5107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memory transactions relative to them. */ 5108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stmtStores 5109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toBool( st->tag == Ist_Store 5110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->tag == Ist_Dirty 5111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || st->tag == Ist_LLSC 5112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || st->tag == Ist_CAS ); 5113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (k = A_NENV-1; k >= 0; k--) { 5115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[k].bindee == NULL) 5116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 5117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compare the actions of this stmt with the actions of 5118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown binding 'k', to see if they invalidate the binding. */ 5119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidateMe 5120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = toBool( 5121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* a store invalidates loaded data */ 5122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (env[k].doesLoad && stmtStores) 5123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* a put invalidates get'd data */ 5124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || (env[k].doesGet && stmtPuts) 5125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* a put invalidates loaded data. Note, we could do 5126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown much better here in the sense that we only need to 5127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidate trees containing loads if the Put in 5128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown question is marked as requiring precise 5129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exceptions. */ 5130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || (env[k].doesLoad && stmtPuts) 5131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* probably overly conservative: a memory bus event 5132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalidates absolutely everything, so that all 5133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown computation prior to it is forced to complete before 5134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown proceeding with the event (fence,lock,unlock). */ 5135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->tag == Ist_MBE 5136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* also be (probably overly) paranoid re AbiHints */ 5137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || st->tag == Ist_AbiHint 5138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 5139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (invalidateMe) { 5140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[j] = IRStmt_WrTmp( env[k].binder, env[k].bindee ); 5141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j++; 5142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(j <= i); 5143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[k].bindee = NULL; 5144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Slide in-use entries in env up to the front */ 5148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown m = 0; 5149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (k = 0; k < A_NENV; k++) { 5150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (env[k].bindee != NULL) { 5151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[m] = env[k]; 5152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown m++; 5153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (m = m; m < A_NENV; m++) { 5156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown env[m].bindee = NULL; 5157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* finally, emit the substituted statement */ 5160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts[j] = st2; 5161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vex_printf("**2 "); ppIRStmt(bb->stmts[j]); vex_printf("\n"); */ 5162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j++; 5163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(j <= i+1); 5165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* for each stmt in the original bb ... */ 5166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Finally ... substitute the ->next field as much as possible, and 5168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dump any left-over bindings. Hmm. Perhaps there should be no 5169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown left over bindings? Or any left-over bindings are 5170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by definition dead? */ 5171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->next = atbSubst_Expr(env, bb->next); 5172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb->stmts_used = j; 5173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 5174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return max_ga_known ? max_ga : ~(Addr64)0; 5175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 5176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- iropt main ---*/ 5180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool iropt_verbose = False; /* True; */ 5183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do a simple cleanup pass on bb. This is: redundant Get removal, 5186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redundant Put removal, constant propagation, dead code removal, 5187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clean helper specialisation, and dead code removal (again). 5188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 5189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 5192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* cheap_transformations ( 5193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb, 5194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int), 5195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*preciseMemExnsFn)(Int,Int) 5196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 5197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 5198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redundant_get_removal_BB ( bb ); 5199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= REDUNDANT GET\n\n" ); 5201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { 5205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng redundant_put_removal_BB ( bb, preciseMemExnsFn ); 5206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 5207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= REDUNDANT PUT\n\n" ); 5209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cprop_BB ( bb ); 5213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= CPROPD\n\n" ); 5215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB ( bb ); 5219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= DEAD\n\n" ); 5221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = spec_helpers_BB ( bb, specHelper ); 5225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB ( bb ); 5226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= SPECd \n\n" ); 5228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bb; 5232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 5233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do some more expensive transformations on bb, which are aimed at 5236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown optimising as much as possible in the presence of GetI and PutI. */ 5237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 5239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* expensive_transformations( IRSB* bb ) 5240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 5241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)do_cse_BB( bb ); 5242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown collapse_AddSub_chains_BB( bb ); 5243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_redundant_GetI_elimination( bb ); 5244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { 5245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng do_redundant_PutI_elimination( bb ); 5246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 5247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB( bb ); 5248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bb; 5249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 5250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Scan a flattened BB to look for signs that more expensive 5253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown optimisations might be useful: 5254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - find out if there are any GetIs and PutIs 5255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - find out if there are any floating or vector-typed temporaries 5256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 5257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void considerExpensives ( /*OUT*/Bool* hasGetIorPutI, 5259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/Bool* hasVorFtemps, 5260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb ) 5261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 5262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, j; 5263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRStmt* st; 5264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRDirty* d; 5265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRCAS* cas; 5266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *hasGetIorPutI = False; 5268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *hasVorFtemps = False; 5269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < bb->stmts_used; i++) { 5271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown st = bb->stmts[i]; 5272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (st->tag) { 5273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_AbiHint: 5274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.base)); 5275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.AbiHint.nia)); 5276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_PutI: 5278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *hasGetIorPutI = True; 5279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_WrTmp: 5281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.WrTmp.data->tag == Iex_GetI) 5282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *hasGetIorPutI = True; 5283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp)) { 5284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ity_I1: case Ity_I8: case Ity_I16: 5285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ity_I32: case Ity_I64: case Ity_I128: 5286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_F32: case Ity_F64: case Ity_F128: 5288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_V128: case Ity_V256: 5289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *hasVorFtemps = True; 5290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 5291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Ity_D32: case Ity_D64: case Ity_D128: 5292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *hasVorFtemps = True; 5293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 5295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto bad; 5296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Put: 5299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Put.data)); 5300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Store: 5302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.addr)); 5303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Store.data)); 5304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_CAS: 5306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cas = st->Ist.CAS.details; 5307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->addr)); 5308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(cas->expdHi == NULL || isIRAtom(cas->expdHi)); 5309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->expdLo)); 5310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(cas->dataHi == NULL || isIRAtom(cas->dataHi)); 5311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(cas->dataLo)); 5312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_LLSC: 5314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.LLSC.addr)); 5315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (st->Ist.LLSC.storedata) 5316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.LLSC.storedata)); 5317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Dirty: 5319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d = st->Ist.Dirty.details; 5320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d->guard)); 5321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; d->args[j]; j++) 5322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d->args[j])); 5323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (d->mFx != Ifx_None) 5324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(d->mAddr)); 5325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_NoOp: 5327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_IMark: 5328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_MBE: 5329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Ist_Exit: 5331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vassert(isIRAtom(st->Ist.Exit.guard)); 5332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 5333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 5334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bad: 5335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRStmt(st); 5336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vpanic("considerExpensives"); 5337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 5340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------- The main iropt entry point. ---------------- */ 5343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* exported from this file */ 5345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Rules of the game: 5346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - IRExpr/IRStmt trees should be treated as immutable, as they 5348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown may get shared. So never change a field of such a tree node; 5349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instead construct and return a new one if needed. 5350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 5351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIRSB* do_iropt_BB( 5354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB* bb0, 5355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRExpr* (*specHelper) (HChar*, IRExpr**, IRStmt**, Int), 5356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool (*preciseMemExnsFn)(Int,Int), 5357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr64 guest_addr, 5358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexArch guest_arch 5359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 5360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 5361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Int n_total = 0; 5362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Int n_expensive = 0; 5363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool hasGetIorPutI, hasVorFtemps; 5365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IRSB *bb, *bb2; 5366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_total++; 5368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First flatten the block out, since all other 5370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phases assume flat code. */ 5371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = flatten_BB ( bb0 ); 5373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (iropt_verbose) { 5375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("\n========= FLAT\n\n" ); 5376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ppIRSB(bb); 5377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If at level 0, stop now. */ 5380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_level <= 0) return bb; 5381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now do a preliminary cleanup pass, and figure out if we also 5383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown need to do 'expensive' optimisations. Expensive optimisations 5384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are deemed necessary if the block contains any GetIs or PutIs. 5385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If needed, do expensive transformations and then another cheap 5386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cleanup pass. */ 5387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cheap_transformations( bb, specHelper, preciseMemExnsFn ); 5389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (guest_arch == VexArchARM) { 5391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Translating Thumb2 code produces a lot of chaff. We have to 5392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown work extra hard to get rid of it. */ 5393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cprop_BB(bb); 5394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = spec_helpers_BB ( bb, specHelper ); 5395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { 5396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng redundant_put_removal_BB ( bb, preciseMemExnsFn ); 5397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 5398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov do_cse_BB( bb ); 5399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB( bb ); 5400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (vex_control.iropt_level > 1) { 5403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Peer at what we have, to decide how much more effort to throw 5405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown at it. */ 5406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown considerExpensives( &hasGetIorPutI, &hasVorFtemps, bb ); 5407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (hasVorFtemps && !hasGetIorPutI) { 5409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If any evidence of FP or Vector activity, CSE, as that 5410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tends to mop up all manner of lardy code to do with 5411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rounding modes. Don't bother if hasGetIorPutI since that 5412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case leads into the expensive transformations, which do 5413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CSE anyway. */ 5414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)do_cse_BB( bb ); 5415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB( bb ); 5416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (hasGetIorPutI) { 5419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool cses; 5420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_expensive++; 5421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DEBUG_IROPT) 5422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vex_printf("***** EXPENSIVE %d %d\n", n_total, n_expensive); 5423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = expensive_transformations( bb ); 5424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cheap_transformations( bb, specHelper, preciseMemExnsFn ); 5425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Potentially common up GetIs */ 5426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cses = do_cse_BB( bb ); 5427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cses) 5428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cheap_transformations( bb, specHelper, preciseMemExnsFn ); 5429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now have a go at unrolling simple (single-BB) loops. If 5432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown successful, clean up the results as much as possible. */ 5433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb2 = maybe_loop_unroll_BB( bb, guest_addr ); 5435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bb2) { 5436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cheap_transformations( bb2, specHelper, preciseMemExnsFn ); 5437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (hasGetIorPutI) { 5438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = expensive_transformations( bb ); 5439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bb = cheap_transformations( bb, specHelper, preciseMemExnsFn ); 5440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 5441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* at least do CSE and dead code removal */ 5442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_cse_BB( bb ); 5443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_deadcode_BB( bb ); 5444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) vex_printf("vex iropt: unrolled a loop\n"); 5446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 5449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return bb; 5451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 5452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ir_opt.c ---*/ 5456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---------------------------------------------------------------*/ 5457