1f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian/* -*- mode: C; c-basic-offset: 3; -*- */ 2a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 3a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 4752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin ir_opt.c ---*/ 5a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 6a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 7f8ed9d874a7b8651654591c68c6d431c758d787csewardj/* 8752f90673ebbb6b2f55fc5e46606dea371313713sewardj This file is part of Valgrind, a dynamic binary instrumentation 9752f90673ebbb6b2f55fc5e46606dea371313713sewardj framework. 10f8ed9d874a7b8651654591c68c6d431c758d787csewardj 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2004-2017 OpenWorks LLP 12752f90673ebbb6b2f55fc5e46606dea371313713sewardj info@open-works.net 137bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 14752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is free software; you can redistribute it and/or 15752f90673ebbb6b2f55fc5e46606dea371313713sewardj modify it under the terms of the GNU General Public License as 16752f90673ebbb6b2f55fc5e46606dea371313713sewardj published by the Free Software Foundation; either version 2 of the 17752f90673ebbb6b2f55fc5e46606dea371313713sewardj License, or (at your option) any later version. 187bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 19752f90673ebbb6b2f55fc5e46606dea371313713sewardj This program is distributed in the hope that it will be useful, but 20752f90673ebbb6b2f55fc5e46606dea371313713sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21752f90673ebbb6b2f55fc5e46606dea371313713sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22752f90673ebbb6b2f55fc5e46606dea371313713sewardj General Public License for more details. 23752f90673ebbb6b2f55fc5e46606dea371313713sewardj 24752f90673ebbb6b2f55fc5e46606dea371313713sewardj You should have received a copy of the GNU General Public License 25752f90673ebbb6b2f55fc5e46606dea371313713sewardj along with this program; if not, write to the Free Software 26752f90673ebbb6b2f55fc5e46606dea371313713sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 02110-1301, USA. 287bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj 29752f90673ebbb6b2f55fc5e46606dea371313713sewardj The GNU General Public License is contained in the file COPYING. 30f8ed9d874a7b8651654591c68c6d431c758d787csewardj 31f8ed9d874a7b8651654591c68c6d431c758d787csewardj Neither the names of the U.S. Department of Energy nor the 32f8ed9d874a7b8651654591c68c6d431c758d787csewardj University of California nor the names of its contributors may be 33f8ed9d874a7b8651654591c68c6d431c758d787csewardj used to endorse or promote products derived from this software 34f8ed9d874a7b8651654591c68c6d431c758d787csewardj without prior written permission. 35f8ed9d874a7b8651654591c68c6d431c758d787csewardj*/ 36f8ed9d874a7b8651654591c68c6d431c758d787csewardj 37a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj#include "libvex_basictypes.h" 38edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj#include "libvex_ir.h" 39a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj#include "libvex.h" 40a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 41cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h" 42cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h" 43cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "ir_opt.h" 44a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 45d0863fff7ceb51db619fea835df0dc9c0ac7cd5bsewardj 46088bcb4521e94c60c1d8a4dd46151e0cd2e06475sewardj/* Set to 1 for lots of debugging output. */ 47088bcb4521e94c60c1d8a4dd46151e0cd2e06475sewardj#define DEBUG_IROPT 0 48088bcb4521e94c60c1d8a4dd46151e0cd2e06475sewardj 49cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Set to 1 to gather some statistics. Currently only for sameIRExprs. */ 50cdb5feebd7e817c8207471ef734b43c51c14dee3florian#define STATS_IROPT 0 51cdb5feebd7e817c8207471ef734b43c51c14dee3florian 52a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* What iropt does, 29 Dec 04. 540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 55f6c8ebf1294fea43756683ba7089b746168abb8esewardj It takes an IRSB and produces a new one with the same meaning, 560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj defined thus: 570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj After execution of the new BB, all guest state and guest memory is 590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj the same as after execution of the original. This is true 600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj regardless of how the block was exited (at the end vs side exit). 610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj In addition, parts of the guest state will be identical to that 630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj created by execution of the original at the following observation 640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj points: 650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * In a dirty helper call, any parts of the guest state that the 670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj helper states that it reads or modifies will be up to date. 680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Also, guest memory will be up to date. Parts of the guest state 690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj not marked as being read or modified by the helper cannot be 700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj assumed to be up-to-date at the point where the helper is called. 710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 726c46befd9eb90c1b6e739926c1fa335cba75bf46philippe * If iropt_register_updates == VexRegUpdSpAtMemAccess : 736c46befd9eb90c1b6e739926c1fa335cba75bf46philippe The guest state is only up to date only as explained above 746c46befd9eb90c1b6e739926c1fa335cba75bf46philippe (i.e. at SB exits and as specified by dirty helper call). 756c46befd9eb90c1b6e739926c1fa335cba75bf46philippe Also, the stack pointer register is up to date at memory 766c46befd9eb90c1b6e739926c1fa335cba75bf46philippe exception points (as this is needed for the stack extension 776c46befd9eb90c1b6e739926c1fa335cba75bf46philippe logic in m_signals.c). 786c46befd9eb90c1b6e739926c1fa335cba75bf46philippe 79c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe * If iropt_register_updates == VexRegUpdUnwindregsAtMemAccess : 80c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe Immediately prior to any load or store, those parts of the guest 810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj state marked as requiring precise exceptions will be up to date. 820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Also, guest memory will be up to date. Parts of the guest state 830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj not marked as requiring precise exceptions cannot be assumed to 840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj be up-to-date at the point of the load/store. 850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 866c46befd9eb90c1b6e739926c1fa335cba75bf46philippe * If iropt_register_updates == VexRegUpdAllregsAtMemAccess: 87c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe Same as minimal, but all the guest state is up to date at memory 88c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe exception points. 89c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe 906c46befd9eb90c1b6e739926c1fa335cba75bf46philippe * If iropt_register_updates == VexRegUpdAllregsAtEachInsn : 91c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe Guest state is up to date at each instruction. 92c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe 930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj The relative order of loads and stores (including loads/stores of 940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj guest memory done by dirty helpers annotated as such) is not 950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj changed. However, the relative order of loads with no intervening 960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj stores/modifies may be changed. 970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Transformation order 990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ~~~~~~~~~~~~~~~~~~~~ 1000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj There are three levels of optimisation, controlled by 1020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_control.iropt_level. Define first: 1030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj "Cheap transformations" are the following sequence: 1050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Redundant-Get removal 1060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Redundant-Put removal 1070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Constant propagation/folding 1080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Dead code removal 1090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Specialisation of clean helper functions 1100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Dead code removal 1110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj "Expensive transformations" are the following sequence: 1130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * CSE 1140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Folding of add/sub chains 1150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Redundant-GetI removal 1160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Redundant-PutI removal 1170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Dead code removal 1180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Then the transformations are as follows, as defined by 1200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_control.iropt_level: 1210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Level 0: 1230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Flatten into atomic form. 1240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Level 1: the following sequence: 1260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Flatten into atomic form. 1270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Cheap transformations. 1280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Level 2: the following sequence 1300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Flatten into atomic form. 1310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Cheap transformations. 132b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj * If block contains any floating or vector types, CSE. 1330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If block contains GetI or PutI, Expensive transformations. 1340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Try unrolling loops. Three possible outcomes: 1350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj - No effect: do nothing more. 1360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj - Unrolled a loop, and block does not contain GetI or PutI: 1370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Do: * CSE 1380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Dead code removal 1390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj - Unrolled a loop, and block contains GetI or PutI: 1400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Do: * Expensive transformations 1410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * Cheap transformations 1420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 1430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 14498430295cf4900160346bfdeea2833bd024b0117sewardj/* Implementation notes, 29 Dec 04. 14598430295cf4900160346bfdeea2833bd024b0117sewardj 14698430295cf4900160346bfdeea2833bd024b0117sewardj TODO (important): I think rPutI removal ignores precise exceptions 14798430295cf4900160346bfdeea2833bd024b0117sewardj and is therefore in a sense, wrong. In the sense that PutIs are 14898430295cf4900160346bfdeea2833bd024b0117sewardj assumed not to write parts of the guest state that we need to have 14998430295cf4900160346bfdeea2833bd024b0117sewardj up-to-date at loads/stores. So far on x86 guest that has not 15098430295cf4900160346bfdeea2833bd024b0117sewardj mattered since indeed only the x87 FP registers and tags are 15198430295cf4900160346bfdeea2833bd024b0117sewardj accessed using GetI/PutI, and there is no need so far for them to 15298430295cf4900160346bfdeea2833bd024b0117sewardj be up to date at mem exception points. The rPutI pass should be 15398430295cf4900160346bfdeea2833bd024b0117sewardj fixed. 154fb44d55a331b6e97d7ba7b18969efec939420707sewardj 1554c5f6d54fa43a98e29a50af85c92720ee61e33c1sewardj TODO: improve pessimistic handling of precise exceptions 1564c5f6d54fa43a98e29a50af85c92720ee61e33c1sewardj in the tree builder. 1574c5f6d54fa43a98e29a50af85c92720ee61e33c1sewardj 158fb44d55a331b6e97d7ba7b18969efec939420707sewardj TODO: check interaction of rGetI and dirty helpers. 159c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj 160c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj F64i constants are treated differently from other constants. 161c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj They are not regarded as atoms, and instead lifted off and 162c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj bound to temps. This allows them to participate in CSE, which 163c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj is important for getting good performance for x86 guest code. 164695cff9303ef5dc8079117acfd632b44edb1f010sewardj 165a5aa9cf3566d1842730cdcbc62a47a344c2944absewardj CSE up F64 literals (already doing F64is) 1664c5f6d54fa43a98e29a50af85c92720ee61e33c1sewardj 1674c5f6d54fa43a98e29a50af85c92720ee61e33c1sewardj CSE: consider carefully the requirement for precise exns 16898430295cf4900160346bfdeea2833bd024b0117sewardj prior to making CSE any more aggressive. */ 169c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj 170c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj 171a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 172a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*--- Finite mappery, of a sort ---*/ 173a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 174a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 1750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* General map from HWord-sized thing HWord-sized thing. Could be by 1760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj hashing, but it's not clear whether or not this would really be any 1770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj faster. */ 178a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 179a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardjtypedef 180a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj struct { 181a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj Bool* inuse; 182ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj HWord* key; 183ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj HWord* val; 184a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj Int size; 185a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj Int used; 186a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 187ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj HashHW; 188a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 189ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardjstatic HashHW* newHHW ( void ) 190a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj{ 191d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian HashHW* h = LibVEX_Alloc_inline(sizeof(HashHW)); 1922963239357452b96dbe6de1b3f8b626ea3305780sewardj h->size = 8; 193a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->used = 0; 194d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian h->inuse = LibVEX_Alloc_inline(h->size * sizeof(Bool)); 195d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian h->key = LibVEX_Alloc_inline(h->size * sizeof(HWord)); 196d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian h->val = LibVEX_Alloc_inline(h->size * sizeof(HWord)); 197a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj return h; 198a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj} 199a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 200a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 20184be73746586afb2ea1f197907fd7271c8d1e2ffsewardj/* Look up key in the map. */ 202a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 203ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardjstatic Bool lookupHHW ( HashHW* h, /*OUT*/HWord* val, HWord key ) 204a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj{ 205a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj Int i; 2060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* vex_printf("lookupHHW(%llx)\n", key ); */ 207a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj for (i = 0; i < h->used; i++) { 208a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj if (h->inuse[i] && h->key[i] == key) { 20939e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj if (val) 21039e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj *val = h->val[i]; 211a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj return True; 212a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 213a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 214a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj return False; 215a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj} 216a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 217a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 218a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/* Add key->val to the map. Replaces any existing binding for key. */ 219a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 220ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardjstatic void addToHHW ( HashHW* h, HWord key, HWord val ) 221a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj{ 222a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj Int i, j; 2230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* vex_printf("addToHHW(%llx, %llx)\n", key, val); */ 224a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 225a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj /* Find and replace existing binding, if any. */ 226a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj for (i = 0; i < h->used; i++) { 227a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj if (h->inuse[i] && h->key[i] == key) { 228a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->val[i] = val; 229a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj return; 230a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 231a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 232a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 233a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj /* Ensure a space is available. */ 234a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj if (h->used == h->size) { 235a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj /* Copy into arrays twice the size. */ 236d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian Bool* inuse2 = LibVEX_Alloc_inline(2 * h->size * sizeof(Bool)); 237d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian HWord* key2 = LibVEX_Alloc_inline(2 * h->size * sizeof(HWord)); 238d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian HWord* val2 = LibVEX_Alloc_inline(2 * h->size * sizeof(HWord)); 239a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj for (i = j = 0; i < h->size; i++) { 240a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj if (!h->inuse[i]) continue; 241a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj inuse2[j] = True; 242a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj key2[j] = h->key[i]; 243a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj val2[j] = h->val[i]; 244a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj j++; 245a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 246a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->used = j; 247a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->size *= 2; 248a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->inuse = inuse2; 249a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->key = key2; 250a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->val = val2; 251a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj } 252a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 253a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj /* Finally, add it. */ 254a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj vassert(h->used < h->size); 255a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->inuse[h->used] = True; 256a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->key[h->used] = key; 25784be73746586afb2ea1f197907fd7271c8d1e2ffsewardj h->val[h->used] = val; 258a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj h->used++; 259a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj} 260a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj 26184be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 262d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj/*---------------------------------------------------------------*/ 2630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Flattening out a BB into atomic SSA form ---*/ 264d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj/*---------------------------------------------------------------*/ 265d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 266e80679ab932e23632e2143788217e02e2a59959fsewardj/* Non-critical helper, heuristic for reducing the number of tmp-tmp 267e80679ab932e23632e2143788217e02e2a59959fsewardj copies made by flattening. If in doubt return False. */ 268e80679ab932e23632e2143788217e02e2a59959fsewardj 269e80679ab932e23632e2143788217e02e2a59959fsewardjstatic Bool isFlat ( IRExpr* e ) 270e80679ab932e23632e2143788217e02e2a59959fsewardj{ 271695cff9303ef5dc8079117acfd632b44edb1f010sewardj if (e->tag == Iex_Get) 272695cff9303ef5dc8079117acfd632b44edb1f010sewardj return True; 273e80679ab932e23632e2143788217e02e2a59959fsewardj if (e->tag == Iex_Binop) 274496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj return toBool( isIRAtom(e->Iex.Binop.arg1) 275496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj && isIRAtom(e->Iex.Binop.arg2) ); 276af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj if (e->tag == Iex_Load) 277af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return isIRAtom(e->Iex.Load.addr); 278e80679ab932e23632e2143788217e02e2a59959fsewardj return False; 279e80679ab932e23632e2143788217e02e2a59959fsewardj} 280e80679ab932e23632e2143788217e02e2a59959fsewardj 281d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj/* Flatten out 'ex' so it is atomic, returning a new expression with 282d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj the same value, after having appended extra IRTemp assignments to 283d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj the end of 'bb'. */ 284d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 285dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic IRExpr* flatten_Expr ( IRSB* bb, IRExpr* ex ) 286d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj{ 287d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj Int i; 288d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj IRExpr** newargs; 289d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj IRType ty = typeOfIRExpr(bb->tyenv, ex); 290d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj IRTemp t1; 291d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 292d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj switch (ex->tag) { 293d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 294d721703a7a904a66c49d0e6318c184d0076b40b0sewardj case Iex_GetI: 295d721703a7a904a66c49d0e6318c184d0076b40b0sewardj t1 = newIRTemp(bb->tyenv, ty); 296dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 2972d3f77c12d2911173fd182d0b6e954196dee9135sewardj IRExpr_GetI(ex->Iex.GetI.descr, 298eeac841fbfcadbc19e97c7ef56bfa3354ba78637sewardj flatten_Expr(bb, ex->Iex.GetI.ix), 2992d3f77c12d2911173fd182d0b6e954196dee9135sewardj ex->Iex.GetI.bias))); 300dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 301d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 302d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Iex_Get: 303d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 304dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, 305dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRStmt_WrTmp(t1, ex)); 306dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 307d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 30896d7cc3e7d54ad5af2af2821223b21f9a8516a59florian case Iex_Qop: { 30996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian IRQop* qop = ex->Iex.Qop.details; 31040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj t1 = newIRTemp(bb->tyenv, ty); 311dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 31296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian IRExpr_Qop(qop->op, 31396d7cc3e7d54ad5af2af2821223b21f9a8516a59florian flatten_Expr(bb, qop->arg1), 31496d7cc3e7d54ad5af2af2821223b21f9a8516a59florian flatten_Expr(bb, qop->arg2), 31596d7cc3e7d54ad5af2af2821223b21f9a8516a59florian flatten_Expr(bb, qop->arg3), 31696d7cc3e7d54ad5af2af2821223b21f9a8516a59florian flatten_Expr(bb, qop->arg4)))); 317dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 31896d7cc3e7d54ad5af2af2821223b21f9a8516a59florian } 31940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj 320420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian case Iex_Triop: { 321420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian IRTriop* triop = ex->Iex.Triop.details; 322b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj t1 = newIRTemp(bb->tyenv, ty); 323dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 324420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian IRExpr_Triop(triop->op, 325420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian flatten_Expr(bb, triop->arg1), 326420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian flatten_Expr(bb, triop->arg2), 327420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian flatten_Expr(bb, triop->arg3)))); 328dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 329420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian } 330b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 331d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Iex_Binop: 332d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 333dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 334d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj IRExpr_Binop(ex->Iex.Binop.op, 335d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj flatten_Expr(bb, ex->Iex.Binop.arg1), 336d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj flatten_Expr(bb, ex->Iex.Binop.arg2)))); 337dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 338d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 339d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Iex_Unop: 340d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 341dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 342d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj IRExpr_Unop(ex->Iex.Unop.op, 343d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj flatten_Expr(bb, ex->Iex.Unop.arg)))); 344dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 345d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 346af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 347d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 348dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 349e768e92e054cde495849a5c842a477d287677f78sewardj IRExpr_Load(ex->Iex.Load.end, 350af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj ex->Iex.Load.ty, 351af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj flatten_Expr(bb, ex->Iex.Load.addr)))); 352dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 353d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 354d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Iex_CCall: 355dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj newargs = shallowCopyIRExprVec(ex->Iex.CCall.args); 356d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj for (i = 0; newargs[i]; i++) 357d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj newargs[i] = flatten_Expr(bb, newargs[i]); 358d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 359dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 3608ea867b06de73d909c29e243407713c291c8414esewardj IRExpr_CCall(ex->Iex.CCall.cee, 361d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj ex->Iex.CCall.retty, 362d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj newargs))); 363dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 364d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 36599dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 366d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj t1 = newIRTemp(bb->tyenv, ty); 367dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 36899dd03e04a6914d90d5fee727d61d76905334becflorian IRExpr_ITE(flatten_Expr(bb, ex->Iex.ITE.cond), 36999dd03e04a6914d90d5fee727d61d76905334becflorian flatten_Expr(bb, ex->Iex.ITE.iftrue), 37099dd03e04a6914d90d5fee727d61d76905334becflorian flatten_Expr(bb, ex->Iex.ITE.iffalse)))); 371dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 372d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 373d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Iex_Const: 374c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj /* Lift F64i constants out onto temps so they can be CSEd 375c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj later. */ 376c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj if (ex->Iex.Const.con->tag == Ico_F64i) { 377c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj t1 = newIRTemp(bb->tyenv, ty); 378dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(t1, 379c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj IRExpr_Const(ex->Iex.Const.con))); 380dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_RdTmp(t1); 381c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj } else { 382c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj /* Leave all other constants alone. */ 383c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj return ex; 384c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj } 385c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj 386dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 387d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj return ex; 388d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 389d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj default: 390d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vex_printf("\n"); 391d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj ppIRExpr(ex); 392d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vex_printf("\n"); 393d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vpanic("flatten_Expr"); 394d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj } 395d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj} 396d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 397d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 398d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj/* Append a completely flattened form of 'st' to the end of 'bb'. */ 399d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 400dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic void flatten_Stmt ( IRSB* bb, IRStmt* st ) 401d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj{ 40217442fe8094d0f82266e5a05509f62cac8f7539esewardj Int i; 403cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr *e1, *e2, *e3, *e4, *e5; 404cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRDirty *d, *d2; 405cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRCAS *cas, *cas2; 406cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRPutI *puti, *puti2; 407cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG *lg; 408cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG *sg; 409d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj switch (st->tag) { 410d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Ist_Put: 411496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if (isIRAtom(st->Ist.Put.data)) { 41249651f4b59b1ab7e0e70cccd34001630eafbe957sewardj /* optimisation to reduce the amount of heap wasted 41349651f4b59b1ab7e0e70cccd34001630eafbe957sewardj by the flattener */ 414dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, st); 41549651f4b59b1ab7e0e70cccd34001630eafbe957sewardj } else { 41649651f4b59b1ab7e0e70cccd34001630eafbe957sewardj /* general case, always correct */ 41749651f4b59b1ab7e0e70cccd34001630eafbe957sewardj e1 = flatten_Expr(bb, st->Ist.Put.data); 418dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_Put(st->Ist.Put.offset, e1)); 41949651f4b59b1ab7e0e70cccd34001630eafbe957sewardj } 420d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj break; 421d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Ist_PutI: 422d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti = st->Ist.PutI.details; 423d6f38b3f822f7d57adfc0da3410995d85d6a4597florian e1 = flatten_Expr(bb, puti->ix); 424d6f38b3f822f7d57adfc0da3410995d85d6a4597florian e2 = flatten_Expr(bb, puti->data); 425d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti2 = mkIRPutI(puti->descr, e1, puti->bias, e2); 426d6f38b3f822f7d57adfc0da3410995d85d6a4597florian addStmtToIRSB(bb, IRStmt_PutI(puti2)); 427d721703a7a904a66c49d0e6318c184d0076b40b0sewardj break; 428dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 429dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (isFlat(st->Ist.WrTmp.data)) { 430e80679ab932e23632e2143788217e02e2a59959fsewardj /* optimisation, to reduce the number of tmp-tmp 431e80679ab932e23632e2143788217e02e2a59959fsewardj copies generated */ 432dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, st); 433e80679ab932e23632e2143788217e02e2a59959fsewardj } else { 434e80679ab932e23632e2143788217e02e2a59959fsewardj /* general case, always correct */ 435dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e1 = flatten_Expr(bb, st->Ist.WrTmp.data); 436dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_WrTmp(st->Ist.WrTmp.tmp, e1)); 437e80679ab932e23632e2143788217e02e2a59959fsewardj } 438d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj break; 439af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 440af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj e1 = flatten_Expr(bb, st->Ist.Store.addr); 441af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj e2 = flatten_Expr(bb, st->Ist.Store.data); 442e768e92e054cde495849a5c842a477d287677f78sewardj addStmtToIRSB(bb, IRStmt_Store(st->Ist.Store.end, e1,e2)); 443e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 444cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: 445cfe046e178666280b87da998b1b52ecda03ecd89sewardj sg = st->Ist.StoreG.details; 446cfe046e178666280b87da998b1b52ecda03ecd89sewardj e1 = flatten_Expr(bb, sg->addr); 447cfe046e178666280b87da998b1b52ecda03ecd89sewardj e2 = flatten_Expr(bb, sg->data); 448cfe046e178666280b87da998b1b52ecda03ecd89sewardj e3 = flatten_Expr(bb, sg->guard); 449cfe046e178666280b87da998b1b52ecda03ecd89sewardj addStmtToIRSB(bb, IRStmt_StoreG(sg->end, e1, e2, e3)); 450cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 451cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: 452cfe046e178666280b87da998b1b52ecda03ecd89sewardj lg = st->Ist.LoadG.details; 453cfe046e178666280b87da998b1b52ecda03ecd89sewardj e1 = flatten_Expr(bb, lg->addr); 454cfe046e178666280b87da998b1b52ecda03ecd89sewardj e2 = flatten_Expr(bb, lg->alt); 455cfe046e178666280b87da998b1b52ecda03ecd89sewardj e3 = flatten_Expr(bb, lg->guard); 456cfe046e178666280b87da998b1b52ecda03ecd89sewardj addStmtToIRSB(bb, IRStmt_LoadG(lg->end, lg->cvt, lg->dst, 457cfe046e178666280b87da998b1b52ecda03ecd89sewardj e1, e2, e3)); 458cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 459e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 460e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 461e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e1 = flatten_Expr(bb, cas->addr); 462e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e2 = cas->expdHi ? flatten_Expr(bb, cas->expdHi) : NULL; 463e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e3 = flatten_Expr(bb, cas->expdLo); 464e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e4 = cas->dataHi ? flatten_Expr(bb, cas->dataHi) : NULL; 465e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e5 = flatten_Expr(bb, cas->dataLo); 466e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas2 = mkIRCAS( cas->oldHi, cas->oldLo, cas->end, 467e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj e1, e2, e3, e4, e5 ); 468e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addStmtToIRSB(bb, IRStmt_CAS(cas2)); 469d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj break; 470e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 471e768e92e054cde495849a5c842a477d287677f78sewardj e1 = flatten_Expr(bb, st->Ist.LLSC.addr); 472e768e92e054cde495849a5c842a477d287677f78sewardj e2 = st->Ist.LLSC.storedata 473e768e92e054cde495849a5c842a477d287677f78sewardj ? flatten_Expr(bb, st->Ist.LLSC.storedata) 474e768e92e054cde495849a5c842a477d287677f78sewardj : NULL; 475e768e92e054cde495849a5c842a477d287677f78sewardj addStmtToIRSB(bb, IRStmt_LLSC(st->Ist.LLSC.end, 476e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.result, e1, e2)); 477e768e92e054cde495849a5c842a477d287677f78sewardj break; 47817442fe8094d0f82266e5a05509f62cac8f7539esewardj case Ist_Dirty: 47917442fe8094d0f82266e5a05509f62cac8f7539esewardj d = st->Ist.Dirty.details; 48017442fe8094d0f82266e5a05509f62cac8f7539esewardj d2 = emptyIRDirty(); 48117442fe8094d0f82266e5a05509f62cac8f7539esewardj *d2 = *d; 482dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj d2->args = shallowCopyIRExprVec(d2->args); 48317442fe8094d0f82266e5a05509f62cac8f7539esewardj if (d2->mFx != Ifx_None) { 48417442fe8094d0f82266e5a05509f62cac8f7539esewardj d2->mAddr = flatten_Expr(bb, d2->mAddr); 48517442fe8094d0f82266e5a05509f62cac8f7539esewardj } else { 48617442fe8094d0f82266e5a05509f62cac8f7539esewardj vassert(d2->mAddr == NULL); 48717442fe8094d0f82266e5a05509f62cac8f7539esewardj } 488b8385d891bddf9016250435f47c06ac44ec921bfsewardj d2->guard = flatten_Expr(bb, d2->guard); 48974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (i = 0; d2->args[i]; i++) { 49074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d2->args[i]; 491ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 49274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj d2->args[i] = flatten_Expr(bb, arg); 49374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 494dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_Dirty(d2)); 49517442fe8094d0f82266e5a05509f62cac8f7539esewardj break; 496d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 497c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 498d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_IMark: 499dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, st); 5003e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj break; 5015a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 5025a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj e1 = flatten_Expr(bb, st->Ist.AbiHint.base); 503478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj e2 = flatten_Expr(bb, st->Ist.AbiHint.nia); 504478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj addStmtToIRSB(bb, IRStmt_AbiHint(e1, st->Ist.AbiHint.len, e2)); 5055a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj break; 506d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj case Ist_Exit: 5070276d4b776bf2152d2ba6bbaec9b150e65d926eesewardj e1 = flatten_Expr(bb, st->Ist.Exit.guard); 508dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb, IRStmt_Exit(e1, st->Ist.Exit.jk, 509c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj st->Ist.Exit.dst, 510c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj st->Ist.Exit.offsIP)); 511d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj break; 512d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj default: 513d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vex_printf("\n"); 514d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj ppIRStmt(st); 515d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vex_printf("\n"); 516d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj vpanic("flatten_Stmt"); 517d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj } 518d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj} 519d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 5200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 521dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic IRSB* flatten_BB ( IRSB* in ) 522d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj{ 523d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj Int i; 524dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB* out; 525dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj out = emptyIRSB(); 526dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj out->tyenv = deepCopyIRTypeEnv( in->tyenv ); 527d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj for (i = 0; i < in->stmts_used; i++) 5284345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (in->stmts[i]) 5294345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj flatten_Stmt( out, in->stmts[i] ); 530d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj out->next = flatten_Expr( out, in->next ); 531d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj out->jumpkind = in->jumpkind; 532c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj out->offsIP = in->offsIP; 533d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj return out; 534d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj} 535d7cb8538d814660fe68ea7100571fd3ed1de8082sewardj 536edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj 53784be73746586afb2ea1f197907fd7271c8d1e2ffsewardj/*---------------------------------------------------------------*/ 5380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- In-place removal of redundant GETs ---*/ 53984be73746586afb2ea1f197907fd7271c8d1e2ffsewardj/*---------------------------------------------------------------*/ 54084be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 5410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Scan forwards, building up an environment binding (min offset, max 5420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj offset) pairs to values, which will either be temps or constants. 543f6501996bf1f0e2a8ce6817efe9edf6b619bc85bsewardj 5440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj On seeing 't = Get(minoff,maxoff)', look up (minoff,maxoff) in the 5450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env and if it matches, replace the Get with the stored value. If 5460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj there is no match, add a (minoff,maxoff) :-> t binding. 5470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj On seeing 'Put (minoff,maxoff) = t or c', first remove in the env 5490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj any binding which fully or partially overlaps with (minoff,maxoff). 5500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Then add a new (minoff,maxoff) :-> t or c binding. */ 5510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Extract the min/max offsets from a guest state array descriptor. */ 5530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjinline 555dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic void getArrayBounds ( IRRegArray* descr, 556dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj UInt* minoff, UInt* maxoff ) 557f672901e88dc8635f4ce834ee5a81edf7079f7edsewardj{ 5580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *minoff = descr->base; 5590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *maxoff = *minoff + descr->nElems*sizeofIRType(descr->elemTy) - 1; 5600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((*minoff & ~0xFFFF) == 0); 5610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((*maxoff & ~0xFFFF) == 0); 5620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(*minoff <= *maxoff); 563f672901e88dc8635f4ce834ee5a81edf7079f7edsewardj} 564f672901e88dc8635f4ce834ee5a81edf7079f7edsewardj 5650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Create keys, of the form ((minoffset << 16) | maxoffset). */ 5660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic UInt mk_key_GetPut ( Int offset, IRType ty ) 568e1d45dace452a557a65efe5419903e8746f93fe3sewardj{ 5690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* offset should fit in 16 bits. */ 5700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt minoff = offset; 5710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt maxoff = minoff + sizeofIRType(ty) - 1; 5720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((minoff & ~0xFFFF) == 0); 5730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((maxoff & ~0xFFFF) == 0); 5740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return (minoff << 16) | maxoff; 575e1d45dace452a557a65efe5419903e8746f93fe3sewardj} 576e1d45dace452a557a65efe5419903e8746f93fe3sewardj 577dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic UInt mk_key_GetIPutI ( IRRegArray* descr ) 57884be73746586afb2ea1f197907fd7271c8d1e2ffsewardj{ 5790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt minoff, maxoff; 5800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj getArrayBounds( descr, &minoff, &maxoff ); 5810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((minoff & ~0xFFFF) == 0); 5820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert((maxoff & ~0xFFFF) == 0); 5830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return (minoff << 16) | maxoff; 5840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 58584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 5860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Supposing h has keys of the form generated by mk_key_GetPut and 5870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj mk_key_GetIPutI, invalidate any key which overlaps (k_lo 5880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj .. k_hi). 5890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 5900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void invalidateOverlaps ( HashHW* h, UInt k_lo, UInt k_hi ) 5910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 5920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int j; 5930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt e_lo, e_hi; 5940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(k_lo <= k_hi); 5950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* invalidate any env entries which in any way overlap (k_lo 5960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj .. k_hi) */ 5970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* vex_printf("invalidate %d .. %d\n", k_lo, k_hi ); */ 598e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 5990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < h->used; j++) { 6000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (!h->inuse[j]) 6010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 6020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e_lo = (((UInt)h->key[j]) >> 16) & 0xFFFF; 6030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e_hi = ((UInt)h->key[j]) & 0xFFFF; 6040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(e_lo <= e_hi); 6050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e_hi < k_lo || k_hi < e_lo) 6060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; /* no overlap possible */ 6070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 6080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* overlap; invalidate */ 6090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj h->inuse[j] = False; 6100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 6110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 612e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 613e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 614dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic void redundant_get_removal_BB ( IRSB* bb ) 6150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 6160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HashHW* env = newHHW(); 6170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt key = 0; /* keep gcc -O happy */ 6180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i, j; 6190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HWord val; 620e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 6210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb->stmts_used; i++) { 6220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st = bb->stmts[i]; 623e1d45dace452a557a65efe5419903e8746f93fe3sewardj 6248bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 6250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 6260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 6270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with Gets */ 628dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp 629dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && st->Ist.WrTmp.data->tag == Iex_Get) { 6300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* st is 't = Get(...)'. Look up in the environment and see 6310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if the Get can be replaced. */ 632dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr* get = st->Ist.WrTmp.data; 6330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj key = (HWord)mk_key_GetPut( get->Iex.Get.offset, 6340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj get->Iex.Get.ty ); 6350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (lookupHHW(env, &val, (HWord)key)) { 6360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* found it */ 6370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Note, we could do better here. If the types are 6380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj different we don't do the substitution, since doing so 6390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj could lead to invalidly-typed IR. An improvement would 6400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj be to stick in a reinterpret-style cast, although that 6410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj would make maintaining flatness more difficult. */ 6420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* valE = (IRExpr*)val; 6439d2e769a9368d2b22c32a4764a70e9da38769628sewardj Bool typesOK = toBool( typeOfIRExpr(bb->tyenv,valE) 644dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj == st->Ist.WrTmp.data->Iex.Get.ty ); 6450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (typesOK && DEBUG_IROPT) { 6460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("rGET: "); ppIRExpr(get); 6470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" -> "); ppIRExpr(valE); 6480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 6490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 6500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (typesOK) 651dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[i] = IRStmt_WrTmp(st->Ist.WrTmp.tmp, valE); 6520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 6530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Not found, but at least we know that t and the Get(...) 6540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj are now associated. So add a binding to reflect that 6550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj fact. */ 6560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addToHHW( env, (HWord)key, 657dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj (HWord)(void*)(IRExpr_RdTmp(st->Ist.WrTmp.tmp)) ); 6581d8ce20698148cd658ab21909c844c2afee20153sewardj } 6590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 6601d8ce20698148cd658ab21909c844c2afee20153sewardj 6610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with Puts: invalidate any env entries overlapped by this 6620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Put */ 6630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Put || st->tag == Ist_PutI) { 6640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt k_lo, k_hi; 6650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Put) { 6660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj key = mk_key_GetPut( st->Ist.Put.offset, 6670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 6680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 6690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(st->tag == Ist_PutI); 670d6f38b3f822f7d57adfc0da3410995d85d6a4597florian key = mk_key_GetIPutI( st->Ist.PutI.details->descr ); 6711d8ce20698148cd658ab21909c844c2afee20153sewardj } 6723701059741f3daf3b926e203311319710ff9cb6fsewardj 6730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj k_lo = (key >> 16) & 0xFFFF; 6740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj k_hi = key & 0xFFFF; 6750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj invalidateOverlaps(env, k_lo, k_hi); 6760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 6770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 6780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Dirty) { 6790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with dirty helpers which write or modify guest state. 6800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Invalidate the entire env. We could do a lot better 6810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj here. */ 6820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRDirty* d = st->Ist.Dirty.details; 6830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool writes = False; 6840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < d->nFxState; j++) { 6850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d->fxState[j].fx == Ifx_Modify 6860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj || d->fxState[j].fx == Ifx_Write) 6870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj writes = True; 6880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 6890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (writes) { 6900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* dump the entire env (not clever, but correct ...) */ 6910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < env->used; j++) 6920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env->inuse[j] = False; 6930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (0) vex_printf("rGET: trash env due to dirty helper\n"); 6940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 69584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj } 69684be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 6970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* add this one to the env, if appropriate */ 6980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Put) { 699496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Put.data)); 7000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addToHHW( env, (HWord)key, (HWord)(st->Ist.Put.data)); 7010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 702e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 7030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* for (i = 0; i < bb->stmts_used; i++) */ 704e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 7050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 706e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 7077447b5b3355ac4201e3bd717989232cf7a0d748csewardj 7080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 7090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- In-place removal of redundant PUTs ---*/ 7100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 711e6b3993279fc50b64b1486546a49643eacf9f45fsewardj 7120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Find any Get uses in st and invalidate any partially or fully 7130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj overlapping ranges listed in env. Due to the flattening phase, the 714dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj only stmt kind we expect to find a Get on is IRStmt_WrTmp. */ 715d9997880a74d96928f3a5154f69df425c9640ab8sewardj 7160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void handle_gets_Stmt ( 7170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HashHW* env, 7180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st, 719ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 720ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl 7210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ) 7220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 7230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int j; 7240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt key = 0; /* keep gcc -O happy */ 7250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool isGet; 7260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool memRW = False; 7270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* e; 728e1d45dace452a557a65efe5419903e8746f93fe3sewardj 7290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 7300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 7310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* This is the only interesting case. Deal with Gets in the RHS 7320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj expression. */ 733dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 734dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e = st->Ist.WrTmp.data; 7350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (e->tag) { 7360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 7370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isGet = True; 7380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj key = mk_key_GetPut ( e->Iex.Get.offset, e->Iex.Get.ty ); 7399bdd2658ffb33e1d9bac768936fae7840af723e6sewardj break; 7400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 7410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isGet = True; 7420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj key = mk_key_GetIPutI ( e->Iex.GetI.descr ); 743e1d45dace452a557a65efe5419903e8746f93fe3sewardj break; 744af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 7450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isGet = False; 7460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj memRW = True; 747088bcb4521e94c60c1d8a4dd46151e0cd2e06475sewardj break; 7480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 7490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isGet = False; 750d721703a7a904a66c49d0e6318c184d0076b40b0sewardj } 7510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (isGet) { 7520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt k_lo, k_hi; 7530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj k_lo = (key >> 16) & 0xFFFF; 7540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj k_hi = key & 0xFFFF; 7550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj invalidateOverlaps(env, k_lo, k_hi); 7560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 7570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 758f672901e88dc8635f4ce834ee5a81edf7079f7edsewardj 7590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Be very conservative for dirty helper calls; dump the entire 7600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj environment. The helper might read guest state, in which 7610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case it needs to be flushed first. Also, the helper might 7620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj access guest memory, in which case all parts of the guest 7630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj state requiring precise exceptions needs to be flushed. The 7640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj crude solution is just to flush everything; we could easily 7650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj enough do a lot better if needed. */ 7663e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj /* Probably also overly-conservative, but also dump everything 767c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj if we hit a memory bus event (fence, lock, unlock). Ditto 768e768e92e054cde495849a5c842a477d287677f78sewardj AbiHints, CASs, LLs and SCs. */ 7695a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 7705a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj vassert(isIRAtom(st->Ist.AbiHint.base)); 771478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj vassert(isIRAtom(st->Ist.AbiHint.nia)); 7725a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj /* fall through */ 773c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 7740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: 775e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 776e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 7770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < env->used; j++) 7780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env->inuse[j] = False; 7790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 780832853b4d71ec6b55031f81bfb1ef49344378068sewardj 7810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* all other cases are boring. */ 782af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 783af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.addr)); 784af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.data)); 7850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj memRW = True; 7860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 787cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 788cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 789cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->addr)); 790cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->data)); 791cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->guard)); 792cfe046e178666280b87da998b1b52ecda03ecd89sewardj memRW = True; 793cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 794cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 795cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 796cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 797cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->addr)); 798cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->alt)); 799cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->guard)); 800cfe046e178666280b87da998b1b52ecda03ecd89sewardj memRW = True; 801cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 802cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 8030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Exit: 804496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Exit.guard)); 8050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 806f672901e88dc8635f4ce834ee5a81edf7079f7edsewardj 807e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian case Ist_Put: 808e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian vassert(isIRAtom(st->Ist.Put.data)); 809e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian break; 810e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian 8110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_PutI: 812d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(st->Ist.PutI.details->ix)); 813d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(st->Ist.PutI.details->data)); 8140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 81584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 816d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 817f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 818f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj break; 819f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj 8200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 8210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 8220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 8230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 8240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("handle_gets_Stmt"); 82584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj } 82684be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 8270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (memRW) { 8286c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* This statement accesses memory. So we might need to dump all parts 8290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj of the environment corresponding to guest state that may not 8300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj be reordered with respect to memory references. That means 8310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj at least the stack pointer. */ 832ca2c3c75784d35d136fc7c952717cdee5063c193sewardj switch (pxControl) { 833c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe case VexRegUpdAllregsAtMemAccess: 834c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe /* Precise exceptions required at mem access. 835c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe Flush all guest state. */ 836c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe for (j = 0; j < env->used; j++) 8370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env->inuse[j] = False; 838c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe break; 8396c46befd9eb90c1b6e739926c1fa335cba75bf46philippe case VexRegUpdSpAtMemAccess: 8406c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* We need to dump the stack pointer 8416c46befd9eb90c1b6e739926c1fa335cba75bf46philippe (needed for stack extension in m_signals.c). 8426c46befd9eb90c1b6e739926c1fa335cba75bf46philippe preciseMemExnsFn will use vex_control.iropt_register_updates 8436c46befd9eb90c1b6e739926c1fa335cba75bf46philippe to verify only the sp is to be checked. */ 8446c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* fallthrough */ 845c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe case VexRegUpdUnwindregsAtMemAccess: 846c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe for (j = 0; j < env->used; j++) { 847c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe if (!env->inuse[j]) 848c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe continue; 849c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe /* Just flush the minimal amount required, as computed by 850c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe preciseMemExnsFn. */ 851c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe HWord k_lo = (env->key[j] >> 16) & 0xFFFF; 852c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe HWord k_hi = env->key[j] & 0xFFFF; 853ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (preciseMemExnsFn( k_lo, k_hi, pxControl )) 854c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe env->inuse[j] = False; 855c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe } 856c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe break; 857e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian case VexRegUpdAllregsAtEachInsn: 858c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe // VexRegUpdAllregsAtEachInsn cannot happen here. 859e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian // fall through 860ca2c3c75784d35d136fc7c952717cdee5063c193sewardj case VexRegUpd_INVALID: 861e74ce2eac51a090a67d28d4801aa51ec52efc7dfflorian default: 862c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe vassert(0); 8630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 8640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* if (memRW) */ 86584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 86684be73746586afb2ea1f197907fd7271c8d1e2ffsewardj} 86784be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 86884be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 8690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Scan backwards, building up a set of (min offset, max 8700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj offset) pairs, indicating those parts of the guest state 8710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for which the next event is a write. 87284be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 8730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj On seeing a conditional exit, empty the set. 87484be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 8750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj On seeing 'Put (minoff,maxoff) = t or c', if (minoff,maxoff) is 8760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj completely within the set, remove the Put. Otherwise, add 8770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (minoff,maxoff) to the set. 878d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 8790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj On seeing 'Get (minoff,maxoff)', remove any part of the set 88098430295cf4900160346bfdeea2833bd024b0117sewardj overlapping (minoff,maxoff). The same has to happen for any events 88198430295cf4900160346bfdeea2833bd024b0117sewardj which implicitly read parts of the guest state: dirty helper calls 88298430295cf4900160346bfdeea2833bd024b0117sewardj and loads/stores. 8830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 88484be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 8850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void redundant_put_removal_BB ( 886dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB* bb, 887ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 888ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl 8890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ) 8900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 8910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i, j; 8920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool isPut; 8930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 8940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt key = 0; /* keep gcc -O happy */ 89584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 896ca2c3c75784d35d136fc7c952717cdee5063c193sewardj vassert(pxControl < VexRegUpdAllregsAtEachInsn); 897c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe 8980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HashHW* env = newHHW(); 899c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 900c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Initialise the running env with the fact that the final exit 901c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj writes the IP (or, whatever it claims to write. We don't 902c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj care.) */ 903c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj key = mk_key_GetPut(bb->offsIP, typeOfIRExpr(bb->tyenv, bb->next)); 904c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj addToHHW(env, (HWord)key, 0); 905c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 906c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* And now scan backwards through the statements. */ 9070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb->stmts_used-1; i >= 0; i--) { 9080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 9098bee6d15808653a71717c256a3abe96993439d25sewardj 9108bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 9110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 91284be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 9130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with conditional exits. */ 9140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Exit) { 915c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj //Bool re_add; 916c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* Need to throw out from the env, any part of it which 917c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj doesn't overlap with the guest state written by this exit. 918c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Since the exit only writes one section, it's simplest to 919c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj do this: (1) check whether env contains a write that 920c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj completely overlaps the write done by this exit; (2) empty 921c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj out env; and (3) if (1) was true, add the write done by 922c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj this exit. 923c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 924c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj To make (1) a bit simpler, merely search for a write that 925c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj exactly matches the one done by this exit. That's safe 926c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj because it will fail as often or more often than a full 927c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj overlap check, and failure to find an overlapping write in 928c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj env is the safe case (we just nuke env if that 929c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj happens). */ 930c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj //vassert(isIRAtom(st->Ist.Exit.guard)); 931c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* (1) */ 932c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj //key = mk_key_GetPut(st->Ist.Exit.offsIP, 933c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj // typeOfIRConst(st->Ist.Exit.dst)); 934c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj //re_add = lookupHHW(env, NULL, key); 935c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* (2) */ 9360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < env->used; j++) 9370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env->inuse[j] = False; 938c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj /* (3) */ 939c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj //if (0 && re_add) 940c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj // addToHHW(env, (HWord)key, 0); 9410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 9420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 94362617eff4fd50854f2b36afeafee10ca28b606f1sewardj 9440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with Puts */ 9450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 9460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 9470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isPut = True; 9480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj key = mk_key_GetPut( st->Ist.Put.offset, 9490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 950496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Put.data)); 9510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 9520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_PutI: 9530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isPut = True; 954d6f38b3f822f7d57adfc0da3410995d85d6a4597florian key = mk_key_GetIPutI( st->Ist.PutI.details->descr ); 955d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(st->Ist.PutI.details->ix)); 956d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(st->Ist.PutI.details->data)); 9570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 9580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 9590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj isPut = False; 9600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 9610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (isPut && st->tag != Ist_PutI) { 9620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* See if any single entry in env overlaps this Put. This is 9630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj simplistic in that the transformation is valid if, say, two 9640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj or more entries in the env overlap this Put, but the use of 9650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj lookupHHW will only find a single entry which exactly 9660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj overlaps this Put. This is suboptimal but safe. */ 9670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (lookupHHW(env, NULL, (HWord)key)) { 9680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* This Put is redundant because a later one will overwrite 9690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj it. So NULL (nop) it out. */ 9700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 9710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("rPUT: "); ppIRStmt(st); 9720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 9730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 974d2445f60726580b450eca68ab40c568f9df338e2sewardj bb->stmts[i] = IRStmt_NoOp(); 9750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 9760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* We can't demonstrate that this Put is redundant, so add it 9770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj to the running collection. */ 9780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addToHHW(env, (HWord)key, 0); 97962617eff4fd50854f2b36afeafee10ca28b606f1sewardj } 9800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 98184be73746586afb2ea1f197907fd7271c8d1e2ffsewardj } 98284be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 9830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Deal with Gets. These remove bits of the environment since 9840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj appearance of a Get means that the next event for that slice 98598430295cf4900160346bfdeea2833bd024b0117sewardj of the guest state is no longer a write, but a read. Also 98698430295cf4900160346bfdeea2833bd024b0117sewardj deals with implicit reads of guest state needed to maintain 98798430295cf4900160346bfdeea2833bd024b0117sewardj precise exceptions. */ 988ca2c3c75784d35d136fc7c952717cdee5063c193sewardj handle_gets_Stmt( env, st, preciseMemExnsFn, pxControl ); 98962617eff4fd50854f2b36afeafee10ca28b606f1sewardj } 99084be73746586afb2ea1f197907fd7271c8d1e2ffsewardj} 99184be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 99284be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 9930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 9940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Constant propagation and folding ---*/ 9950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 99684be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 997cdb5feebd7e817c8207471ef734b43c51c14dee3florian#if STATS_IROPT 998cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* How often sameIRExprs was invoked */ 999cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt invocation_count; 1000cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* How often sameIRExprs recursed through IRTemp assignments */ 1001cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt recursion_count; 1002cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* How often sameIRExprs found identical IRExprs */ 1003cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt success_count; 1004cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* How often recursing through assignments to IRTemps helped 1005cdb5feebd7e817c8207471ef734b43c51c14dee3florian establishing equality. */ 1006cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt recursion_success_count; 1007cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Whether or not recursing through an IRTemp assignment helped 1008cdb5feebd7e817c8207471ef734b43c51c14dee3florian establishing IRExpr equality for a given sameIRExprs invocation. */ 1009cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic Bool recursion_helped; 1010cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Whether or not a given sameIRExprs invocation recursed through an 1011cdb5feebd7e817c8207471ef734b43c51c14dee3florian IRTemp assignment */ 1012cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic Bool recursed; 1013cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Maximum number of nodes ever visited when comparing two IRExprs. */ 1014cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt max_nodes_visited; 1015cdb5feebd7e817c8207471ef734b43c51c14dee3florian#endif /* STATS_IROPT */ 1016cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1017cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Count the number of nodes visited for a given sameIRExprs invocation. */ 1018cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic UInt num_nodes_visited; 1019cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1020cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Do not visit more than NODE_LIMIT nodes when comparing two IRExprs. 1021cdb5feebd7e817c8207471ef734b43c51c14dee3florian This is to guard against performance degradation by visiting large 1022cdb5feebd7e817c8207471ef734b43c51c14dee3florian trees without success. */ 1023cdb5feebd7e817c8207471ef734b43c51c14dee3florian#define NODE_LIMIT 30 1024cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1025cdb5feebd7e817c8207471ef734b43c51c14dee3florian 10260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* The env in this section is a map from IRTemp to IRExpr*, 10270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj that is, an array indexed by IRTemp. */ 102884be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 1029cdb5feebd7e817c8207471ef734b43c51c14dee3florian/* Do both expressions compute the same value? The answer is generally 1030cdb5feebd7e817c8207471ef734b43c51c14dee3florian conservative, i.e. it will report that the expressions do not compute 1031cdb5feebd7e817c8207471ef734b43c51c14dee3florian the same value when in fact they do. The reason is that we do not 1032cdb5feebd7e817c8207471ef734b43c51c14dee3florian keep track of changes in the guest state and memory. Thusly, two 1033cdb5feebd7e817c8207471ef734b43c51c14dee3florian Get's, GetI's or Load's, even when accessing the same location, will be 1034cdb5feebd7e817c8207471ef734b43c51c14dee3florian assumed to compute different values. After all the accesses may happen 1035cdb5feebd7e817c8207471ef734b43c51c14dee3florian at different times and the guest state / memory can have changed in 1036a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj the meantime. 1037a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj 1038a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj XXX IMPORTANT XXX the two expressions must have the same IR type. 1039a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj DO NOT CALL HERE WITH DIFFERENTLY-TYPED EXPRESSIONS. */ 1040c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 1041c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* JRS 20-Mar-2012: split sameIRExprs_aux into a fast inlineable 1042c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj wrapper that deals with the common tags-don't-match case, and a 1043c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj slower out of line general case. Saves a few insns. */ 1044c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 1045c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj__attribute__((noinline)) 1046c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjstatic Bool sameIRExprs_aux2 ( IRExpr** env, IRExpr* e1, IRExpr* e2 ); 1047c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 1048c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjinline 1049cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic Bool sameIRExprs_aux ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 10500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 1051cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (e1->tag != e2->tag) return False; 1052c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return sameIRExprs_aux2(env, e1, e2); 1053c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj} 1054d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1055c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj__attribute__((noinline)) 1056c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjstatic Bool sameIRExprs_aux2 ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 1057c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj{ 1058cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (num_nodes_visited++ > NODE_LIMIT) return False; 10596c299f3acab617581ea504e45fbb6cab24c2b29fsewardj 10606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj switch (e1->tag) { 10616c299f3acab617581ea504e45fbb6cab24c2b29fsewardj case Iex_RdTmp: 1062cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (e1->Iex.RdTmp.tmp == e2->Iex.RdTmp.tmp) return True; 1063cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1064cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (env[e1->Iex.RdTmp.tmp] && env[e2->Iex.RdTmp.tmp]) { 1065cdb5feebd7e817c8207471ef734b43c51c14dee3florian Bool same = sameIRExprs_aux(env, env[e1->Iex.RdTmp.tmp], 1066cdb5feebd7e817c8207471ef734b43c51c14dee3florian env[e2->Iex.RdTmp.tmp]); 1067cdb5feebd7e817c8207471ef734b43c51c14dee3florian#if STATS_IROPT 1068cdb5feebd7e817c8207471ef734b43c51c14dee3florian recursed = True; 1069cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (same) recursion_helped = True; 1070cdb5feebd7e817c8207471ef734b43c51c14dee3florian#endif 1071cdb5feebd7e817c8207471ef734b43c51c14dee3florian return same; 1072cdb5feebd7e817c8207471ef734b43c51c14dee3florian } 10736c299f3acab617581ea504e45fbb6cab24c2b29fsewardj return False; 1074cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1075cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_Get: 1076cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_GetI: 1077cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_Load: 1078cdb5feebd7e817c8207471ef734b43c51c14dee3florian /* Guest state / memory could have changed in the meantime. */ 1079cdb5feebd7e817c8207471ef734b43c51c14dee3florian return False; 1080cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1081cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_Binop: 1082cdb5feebd7e817c8207471ef734b43c51c14dee3florian return toBool( e1->Iex.Binop.op == e2->Iex.Binop.op 10836399f81e98cd8c7fbd55255c67f051a0a1873658sewardj && sameIRExprs_aux( env, e1->Iex.Binop.arg1, 10846399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e2->Iex.Binop.arg1 ) 10856399f81e98cd8c7fbd55255c67f051a0a1873658sewardj && sameIRExprs_aux( env, e1->Iex.Binop.arg2, 10866399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e2->Iex.Binop.arg2 )); 1087cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1088cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_Unop: 1089cdb5feebd7e817c8207471ef734b43c51c14dee3florian return toBool( e1->Iex.Unop.op == e2->Iex.Unop.op 10906399f81e98cd8c7fbd55255c67f051a0a1873658sewardj && sameIRExprs_aux( env, e1->Iex.Unop.arg, 10916399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e2->Iex.Unop.arg )); 1092cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1093cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Iex_Const: { 1094cdb5feebd7e817c8207471ef734b43c51c14dee3florian IRConst *c1 = e1->Iex.Const.con; 1095cdb5feebd7e817c8207471ef734b43c51c14dee3florian IRConst *c2 = e2->Iex.Const.con; 1096cdb5feebd7e817c8207471ef734b43c51c14dee3florian vassert(c1->tag == c2->tag); 1097cdb5feebd7e817c8207471ef734b43c51c14dee3florian switch (c1->tag) { 1098cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Ico_U1: return toBool( c1->Ico.U1 == c2->Ico.U1 ); 1099cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Ico_U8: return toBool( c1->Ico.U8 == c2->Ico.U8 ); 1100cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Ico_U16: return toBool( c1->Ico.U16 == c2->Ico.U16 ); 1101cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Ico_U32: return toBool( c1->Ico.U32 == c2->Ico.U32 ); 1102cdb5feebd7e817c8207471ef734b43c51c14dee3florian case Ico_U64: return toBool( c1->Ico.U64 == c2->Ico.U64 ); 1103cdb5feebd7e817c8207471ef734b43c51c14dee3florian default: break; 1104cdb5feebd7e817c8207471ef734b43c51c14dee3florian } 1105cdb5feebd7e817c8207471ef734b43c51c14dee3florian return False; 1106cdb5feebd7e817c8207471ef734b43c51c14dee3florian } 1107cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1108420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian case Iex_Triop: { 1109420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian IRTriop *tri1 = e1->Iex.Triop.details; 1110420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian IRTriop *tri2 = e2->Iex.Triop.details; 1111420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian return toBool( tri1->op == tri2->op 1112420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian && sameIRExprs_aux( env, tri1->arg1, tri2->arg1 ) 1113420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian && sameIRExprs_aux( env, tri1->arg2, tri2->arg2 ) 1114420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian && sameIRExprs_aux( env, tri1->arg3, tri2->arg3 )); 1115420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian } 1116cdb5feebd7e817c8207471ef734b43c51c14dee3florian 111799dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 111899dd03e04a6914d90d5fee727d61d76905334becflorian return toBool( sameIRExprs_aux( env, e1->Iex.ITE.cond, 111999dd03e04a6914d90d5fee727d61d76905334becflorian e2->Iex.ITE.cond ) 112099dd03e04a6914d90d5fee727d61d76905334becflorian && sameIRExprs_aux( env, e1->Iex.ITE.iftrue, 112199dd03e04a6914d90d5fee727d61d76905334becflorian e2->Iex.ITE.iftrue ) 112299dd03e04a6914d90d5fee727d61d76905334becflorian && sameIRExprs_aux( env, e1->Iex.ITE.iffalse, 112399dd03e04a6914d90d5fee727d61d76905334becflorian e2->Iex.ITE.iffalse )); 1124cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1125cdb5feebd7e817c8207471ef734b43c51c14dee3florian default: 1126cdb5feebd7e817c8207471ef734b43c51c14dee3florian /* Not very likely to be "same". */ 1127cdb5feebd7e817c8207471ef734b43c51c14dee3florian break; 11286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 1129cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1130cdb5feebd7e817c8207471ef734b43c51c14dee3florian return False; 1131cdb5feebd7e817c8207471ef734b43c51c14dee3florian} 1132cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1133c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardjinline 1134cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic Bool sameIRExprs ( IRExpr** env, IRExpr* e1, IRExpr* e2 ) 1135cdb5feebd7e817c8207471ef734b43c51c14dee3florian{ 1136cdb5feebd7e817c8207471ef734b43c51c14dee3florian Bool same; 1137cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1138cdb5feebd7e817c8207471ef734b43c51c14dee3florian num_nodes_visited = 0; 1139cdb5feebd7e817c8207471ef734b43c51c14dee3florian same = sameIRExprs_aux(env, e1, e2); 1140cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1141cdb5feebd7e817c8207471ef734b43c51c14dee3florian#if STATS_IROPT 1142cdb5feebd7e817c8207471ef734b43c51c14dee3florian ++invocation_count; 1143cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (recursed) ++recursion_count; 1144cdb5feebd7e817c8207471ef734b43c51c14dee3florian success_count += same; 1145cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (same && recursion_helped) 1146cdb5feebd7e817c8207471ef734b43c51c14dee3florian ++recursion_success_count; 1147cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (num_nodes_visited > max_nodes_visited) 1148cdb5feebd7e817c8207471ef734b43c51c14dee3florian max_nodes_visited = num_nodes_visited; 1149cdb5feebd7e817c8207471ef734b43c51c14dee3florian recursed = False; /* reset */ 1150cdb5feebd7e817c8207471ef734b43c51c14dee3florian recursion_helped = False; /* reset */ 1151cdb5feebd7e817c8207471ef734b43c51c14dee3florian#endif /* STATS_IROPT */ 1152cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1153cdb5feebd7e817c8207471ef734b43c51c14dee3florian return same; 11546c299f3acab617581ea504e45fbb6cab24c2b29fsewardj} 11556c299f3acab617581ea504e45fbb6cab24c2b29fsewardj 1156cdb5feebd7e817c8207471ef734b43c51c14dee3florian 1157a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj/* Debugging-only hack (not used in production runs): make a guess 1158a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj whether sameIRExprs might assert due to the two args being of 1159a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj different types. If in doubt return False. Is only used when 1160a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj --vex-iropt-level > 0, that is, vex_control.iropt_verbosity > 0. 1161a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj Bad because it duplicates functionality from typeOfIRExpr. See 1162a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj comment on the single use point below for rationale. */ 1163a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardjstatic 1164a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardjBool debug_only_hack_sameIRExprs_might_assert ( IRExpr* e1, IRExpr* e2 ) 1165a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj{ 1166a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj if (e1->tag != e2->tag) return False; 1167a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj switch (e1->tag) { 1168a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj case Iex_Const: { 1169a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj /* The only interesting case */ 1170a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj IRConst *c1 = e1->Iex.Const.con; 1171a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj IRConst *c2 = e2->Iex.Const.con; 1172a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj return c1->tag != c2->tag; 1173a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj } 1174a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj default: 1175a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj break; 1176a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj } 1177a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj return False; 1178a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj} 1179a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj 1180a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj 1181ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian/* Is this literally IRExpr_Const(IRConst_U32(0)) ? */ 1182ea7eab702d1aab9dae54bf323cef4fc7c91e0025florianstatic Bool isZeroU32 ( IRExpr* e ) 1183ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian{ 1184ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian return toBool( e->tag == Iex_Const 1185ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian && e->Iex.Const.con->tag == Ico_U32 1186ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian && e->Iex.Const.con->Ico.U32 == 0); 1187ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian} 1188ea7eab702d1aab9dae54bf323cef4fc7c91e0025florian 118940226d12a7e6563e74cda5349e72d88f74160a0bflorian/* Is this literally IRExpr_Const(IRConst_U64(0)) ? 119040226d12a7e6563e74cda5349e72d88f74160a0bflorian Currently unused; commented out to avoid compiler warning */ 119140226d12a7e6563e74cda5349e72d88f74160a0bflorian#if 0 1192bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardjstatic Bool isZeroU64 ( IRExpr* e ) 1193bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj{ 1194bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj return toBool( e->tag == Iex_Const 1195bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj && e->Iex.Const.con->tag == Ico_U64 1196bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj && e->Iex.Const.con->Ico.U64 == 0); 1197bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj} 119840226d12a7e6563e74cda5349e72d88f74160a0bflorian#endif 1199bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj 12009571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj/* Is this literally IRExpr_Const(IRConst_V128(0)) ? */ 12019571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardjstatic Bool isZeroV128 ( IRExpr* e ) 12029571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj{ 12039571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj return toBool( e->tag == Iex_Const 12049571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj && e->Iex.Const.con->tag == Ico_V128 12059571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj && e->Iex.Const.con->Ico.V128 == 0x0000); 12069571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj} 12079571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj 12089571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj/* Is this literally IRExpr_Const(IRConst_V256(0)) ? */ 12099571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardjstatic Bool isZeroV256 ( IRExpr* e ) 12109571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj{ 12119571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj return toBool( e->tag == Iex_Const 12129571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj && e->Iex.Const.con->tag == Ico_V256 12139571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj && e->Iex.Const.con->Ico.V256 == 0x00000000); 12149571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj} 12159571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj 1216f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian/* Is this an integer constant with value 0 ? */ 1217f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorianstatic Bool isZeroU ( IRExpr* e ) 1218f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian{ 1219f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (e->tag != Iex_Const) return False; 1220f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian switch (e->Iex.Const.con->tag) { 1221f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Ico_U1: return toBool( e->Iex.Const.con->Ico.U1 == 0); 1222f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Ico_U8: return toBool( e->Iex.Const.con->Ico.U8 == 0); 1223f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Ico_U16: return toBool( e->Iex.Const.con->Ico.U16 == 0); 1224f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Ico_U32: return toBool( e->Iex.Const.con->Ico.U32 == 0); 1225f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Ico_U64: return toBool( e->Iex.Const.con->Ico.U64 == 0); 1226a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes case Ico_V256: return toBool( e->Iex.Const.con->Ico.V256 == 0x00000000); 1227f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian default: vpanic("isZeroU"); 1228f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 1229f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian} 1230f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 1231cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj/* Is this an integer constant with value 1---1b ? */ 1232cf4be4a70cb7393839b68fad19e3660e2c053b57sewardjstatic Bool isOnesU ( IRExpr* e ) 1233cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj{ 1234cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj if (e->tag != Iex_Const) return False; 1235cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj switch (e->Iex.Const.con->tag) { 1236cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Ico_U8: return toBool( e->Iex.Const.con->Ico.U8 == 0xFF); 1237cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Ico_U16: return toBool( e->Iex.Const.con->Ico.U16 == 0xFFFF); 1238cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Ico_U32: return toBool( e->Iex.Const.con->Ico.U32 1239cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj == 0xFFFFFFFF); 1240cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Ico_U64: return toBool( e->Iex.Const.con->Ico.U64 1241cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj == 0xFFFFFFFFFFFFFFFFULL); 1242cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj default: ppIRExpr(e); vpanic("isOnesU"); 1243cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj } 1244cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj} 1245cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj 12460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic Bool notBool ( Bool b ) 12470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 12480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (b == True) return False; 12490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (b == False) return True; 12500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("notBool"); 12510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 125284be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 12530033ddccac6f90789fe2e78e86b8a649931d77b4sewardj/* Make a zero which has the same type as the result of the given 12540033ddccac6f90789fe2e78e86b8a649931d77b4sewardj primop. */ 125564d776c37f5dcb3475b0ca99aaafa448ba98b717sewardjstatic IRExpr* mkZeroOfPrimopResultType ( IROp op ) 12560033ddccac6f90789fe2e78e86b8a649931d77b4sewardj{ 12570033ddccac6f90789fe2e78e86b8a649931d77b4sewardj switch (op) { 1258a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj case Iop_CmpNE32: return IRExpr_Const(IRConst_U1(toBool(0))); 12590033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_Xor8: return IRExpr_Const(IRConst_U8(0)); 12600033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_Xor16: return IRExpr_Const(IRConst_U16(0)); 1261be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj case Iop_Sub32: 12620033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_Xor32: return IRExpr_Const(IRConst_U32(0)); 1263bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj case Iop_And64: 126464d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_Sub64: 12650033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_Xor64: return IRExpr_Const(IRConst_U64(0)); 126636a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj case Iop_XorV128: 126736a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj case Iop_AndV128: return IRExpr_Const(IRConst_V128(0)); 126870dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Iop_XorV256: 12691b7c4719bc445c8e71230e58e62050d67aaf0109florian case Iop_AndV256: return IRExpr_Const(IRConst_V256(0)); 127064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj default: vpanic("mkZeroOfPrimopResultType: bad primop"); 127164d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj } 127264d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj} 127364d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj 127464d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj/* Make a value containing all 1-bits, which has the same type as the 127564d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj result of the given primop. */ 127664d776c37f5dcb3475b0ca99aaafa448ba98b717sewardjstatic IRExpr* mkOnesOfPrimopResultType ( IROp op ) 127764d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj{ 127864d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj switch (op) { 1279a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj case Iop_CmpEQ32: 128064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ64: 128164d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj return IRExpr_Const(IRConst_U1(toBool(1))); 1282cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Iop_Or8: 1283cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj return IRExpr_Const(IRConst_U8(0xFF)); 1284cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Iop_Or16: 1285cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj return IRExpr_Const(IRConst_U16(0xFFFF)); 1286cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Iop_Or32: 1287cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj return IRExpr_Const(IRConst_U32(0xFFFFFFFF)); 128864d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ8x8: 1289cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj case Iop_Or64: 129064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj return IRExpr_Const(IRConst_U64(0xFFFFFFFFFFFFFFFFULL)); 129164d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ8x16: 1292899d1838d6fd60b141a3d808b02dc04be5901681sewardj case Iop_CmpEQ16x8: 1293ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj case Iop_CmpEQ32x4: 129464d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj return IRExpr_Const(IRConst_V128(0xFFFF)); 129564d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj default: 1296cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj ppIROp(op); 129764d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj vpanic("mkOnesOfPrimopResultType: bad primop"); 12980033ddccac6f90789fe2e78e86b8a649931d77b4sewardj } 12990033ddccac6f90789fe2e78e86b8a649931d77b4sewardj} 13000033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 13014cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj/* Helpers for folding Clz32/64. */ 13024cba9f4d2f3b9999586c56fc8507d50df8607a74sewardjstatic UInt fold_Clz64 ( ULong value ) 13034cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj{ 13044cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj UInt i; 13054cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj vassert(value != 0ULL); /* no defined semantics for arg==0 */ 13064cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj for (i = 0; i < 64; ++i) { 13077f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj if (0ULL != (value & (((ULong)1) << (63 - i)))) return i; 13084cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj } 13094cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj vassert(0); 13104cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj /*NOTREACHED*/ 13114cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj return 0; 13124cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj} 13134cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj 13144cba9f4d2f3b9999586c56fc8507d50df8607a74sewardjstatic UInt fold_Clz32 ( UInt value ) 13154cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj{ 13164cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj UInt i; 13174cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj vassert(value != 0); /* no defined semantics for arg==0 */ 13184cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj for (i = 0; i < 32; ++i) { 13197f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj if (0 != (value & (((UInt)1) << (31 - i)))) return i; 13204cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj } 13214cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj vassert(0); 13224cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj /*NOTREACHED*/ 13234cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj return 0; 13244cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj} 13254cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj 13264a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj/* V64 holds 8 summary-constant bits in V128/V256 style. Convert to 13274a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj the corresponding real constant. */ 13284a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj//XXX re-check this before use 13294a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj//static ULong de_summarise_V64 ( UChar v64 ) 13304a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj//{ 13314a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// ULong r = 0; 13324a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<0)) r |= 0x00000000000000FFULL; 13334a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<1)) r |= 0x000000000000FF00ULL; 13344a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<2)) r |= 0x0000000000FF0000ULL; 13354a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<3)) r |= 0x00000000FF000000ULL; 13364a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<4)) r |= 0x000000FF00000000ULL; 13374a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<5)) r |= 0x0000FF0000000000ULL; 13384a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<6)) r |= 0x00FF000000000000ULL; 13394a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// if (v64 & (1<<7)) r |= 0xFF00000000000000ULL; 13404a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj// return r; 13414a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj//} 13420033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 1343009230b9758291b594e60d7c0243a73d53e81854sewardj/* Helper for arbitrary expression pattern matching in flat IR. If 1344009230b9758291b594e60d7c0243a73d53e81854sewardj 'e' is a reference to a tmp, look it up in env -- repeatedly, if 1345009230b9758291b594e60d7c0243a73d53e81854sewardj necessary -- until it resolves to a non-tmp. Note that this can 1346009230b9758291b594e60d7c0243a73d53e81854sewardj return NULL if it can't resolve 'e' to a new expression, which will 1347009230b9758291b594e60d7c0243a73d53e81854sewardj be the case if 'e' is instead defined by an IRStmt (IRDirty or 1348009230b9758291b594e60d7c0243a73d53e81854sewardj LLSC). */ 1349009230b9758291b594e60d7c0243a73d53e81854sewardjstatic IRExpr* chase ( IRExpr** env, IRExpr* e ) 1350009230b9758291b594e60d7c0243a73d53e81854sewardj{ 1351009230b9758291b594e60d7c0243a73d53e81854sewardj /* Why is this loop guaranteed to terminate? Because all tmps must 1352009230b9758291b594e60d7c0243a73d53e81854sewardj have definitions before use, hence a tmp cannot be bound 1353009230b9758291b594e60d7c0243a73d53e81854sewardj (directly or indirectly) to itself. */ 1354009230b9758291b594e60d7c0243a73d53e81854sewardj while (e->tag == Iex_RdTmp) { 1355009230b9758291b594e60d7c0243a73d53e81854sewardj if (0) { vex_printf("chase "); ppIRExpr(e); vex_printf("\n"); } 1356009230b9758291b594e60d7c0243a73d53e81854sewardj e = env[(Int)e->Iex.RdTmp.tmp]; 1357009230b9758291b594e60d7c0243a73d53e81854sewardj if (e == NULL) break; 1358009230b9758291b594e60d7c0243a73d53e81854sewardj } 1359009230b9758291b594e60d7c0243a73d53e81854sewardj return e; 1360009230b9758291b594e60d7c0243a73d53e81854sewardj} 1361009230b9758291b594e60d7c0243a73d53e81854sewardj 136216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* Similar to |chase|, but follows at most one level of tmp reference. */ 136316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic IRExpr* chase1 ( IRExpr** env, IRExpr* e ) 136416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 136516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (e == NULL || e->tag != Iex_RdTmp) 136616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return e; 136716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj else 136816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return env[(Int)e->Iex.RdTmp.tmp]; 136916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 137016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 1371cdb5feebd7e817c8207471ef734b43c51c14dee3florianstatic IRExpr* fold_Expr ( IRExpr** env, IRExpr* e ) 13720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 13730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int shift; 13740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* e2 = e; /* e2 is the result of folding e, if possible */ 137584be73746586afb2ea1f197907fd7271c8d1e2ffsewardj 1376708417d56d1798ffd62a05b7932da47cdc3d3337florian switch (e->tag) { 1377708417d56d1798ffd62a05b7932da47cdc3d3337florian case Iex_Unop: 1378708417d56d1798ffd62a05b7932da47cdc3d3337florian /* UNARY ops */ 1379708417d56d1798ffd62a05b7932da47cdc3d3337florian if (e->Iex.Unop.arg->tag == Iex_Const) { 1380708417d56d1798ffd62a05b7932da47cdc3d3337florian switch (e->Iex.Unop.op) { 13810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_1Uto8: 13829d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 13830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 13849d2e769a9368d2b22c32a4764a70e9da38769628sewardj ? 1 : 0))); 13850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 13860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_1Uto32: 13870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 13880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 13890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? 1 : 0)); 13900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 13912716ff157eb1a0351fcfa3aba8671aee198a9448sewardj case Iop_1Uto64: 13922716ff157eb1a0351fcfa3aba8671aee198a9448sewardj e2 = IRExpr_Const(IRConst_U64( 13932716ff157eb1a0351fcfa3aba8671aee198a9448sewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 13942716ff157eb1a0351fcfa3aba8671aee198a9448sewardj ? 1 : 0)); 13952716ff157eb1a0351fcfa3aba8671aee198a9448sewardj break; 139662617eff4fd50854f2b36afeafee10ca28b606f1sewardj 13971bee561912427ca8f8998c89b62d86ba2ee49732sewardj case Iop_1Sto8: 13981bee561912427ca8f8998c89b62d86ba2ee49732sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 13991bee561912427ca8f8998c89b62d86ba2ee49732sewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 14001bee561912427ca8f8998c89b62d86ba2ee49732sewardj ? 0xFF : 0))); 14011bee561912427ca8f8998c89b62d86ba2ee49732sewardj break; 140268884efaa49d8454fa4b036af98af5339343f148sewardj case Iop_1Sto16: 1403743d8f0a1b1dfee13633307d11725e2124707db0sewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 140468884efaa49d8454fa4b036af98af5339343f148sewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 1405743d8f0a1b1dfee13633307d11725e2124707db0sewardj ? 0xFFFF : 0))); 140668884efaa49d8454fa4b036af98af5339343f148sewardj break; 14070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_1Sto32: 14080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 14090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 14100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? 0xFFFFFFFF : 0)); 14110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_1Sto64: 14130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U64( 14140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Unop.arg->Iex.Const.con->Ico.U1 14150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? 0xFFFFFFFFFFFFFFFFULL : 0)); 14160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 141717442fe8094d0f82266e5a05509f62cac8f7539esewardj 14180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_8Sto32: { 1419108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U8; 1420108e03fcb0a4ef42164235b1988aa540aa1e5298florian u32 <<= 24; 1421108e03fcb0a4ef42164235b1988aa540aa1e5298florian u32 = (Int)u32 >> 24; /* signed shift */ 1422108e03fcb0a4ef42164235b1988aa540aa1e5298florian e2 = IRExpr_Const(IRConst_U32(u32)); 14230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1424b8e7586be6001ff697d561160e089b0232784896sewardj } 14257f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_16Sto32: { 1426108e03fcb0a4ef42164235b1988aa540aa1e5298florian UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1427108e03fcb0a4ef42164235b1988aa540aa1e5298florian u32 <<= 16; 1428108e03fcb0a4ef42164235b1988aa540aa1e5298florian u32 = (Int)u32 >> 16; /* signed shift */ 1429108e03fcb0a4ef42164235b1988aa540aa1e5298florian e2 = IRExpr_Const(IRConst_U32(u32)); 14307f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 14317f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj } 1432291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj case Iop_8Uto64: 1433291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj e2 = IRExpr_Const(IRConst_U64( 1434291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj 0xFFULL & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 1435291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj break; 1436291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj case Iop_16Uto64: 1437291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj e2 = IRExpr_Const(IRConst_U64( 1438291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj 0xFFFFULL & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)); 1439291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj break; 14400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_8Uto32: 14410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 14420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 14430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14447f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_8Sto16: { 1445108e03fcb0a4ef42164235b1988aa540aa1e5298florian UShort u16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U8; 1446108e03fcb0a4ef42164235b1988aa540aa1e5298florian u16 <<= 8; 1447108e03fcb0a4ef42164235b1988aa540aa1e5298florian u16 = (Short)u16 >> 8; /* signed shift */ 1448108e03fcb0a4ef42164235b1988aa540aa1e5298florian e2 = IRExpr_Const(IRConst_U16(u16)); 14497f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 14507f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj } 14517f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_8Uto16: 14527f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U16( 14537f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8)); 14547f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 14550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_16Uto32: 14560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 14570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U16)); 14580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_32to16: 14609d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 14619d2e769a9368d2b22c32a4764a70e9da38769628sewardj 0xFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 14620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_32to8: 14649d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 14659d2e769a9368d2b22c32a4764a70e9da38769628sewardj 0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 14660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_32to1: 14689d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 14699d2e769a9368d2b22c32a4764a70e9da38769628sewardj 1 == (1 & e->Iex.Unop.arg->Iex.Const.con->Ico.U32) 14709d2e769a9368d2b22c32a4764a70e9da38769628sewardj ))); 14710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1472291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj case Iop_64to1: 1473291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 1474291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj 1 == (1 & e->Iex.Unop.arg->Iex.Const.con->Ico.U64) 1475291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj ))); 1476291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj break; 147739e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj 14784a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_NotV128: 14794a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128( 14804a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.V128))); 14814a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 1482f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj case Iop_Not64: 1483f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj e2 = IRExpr_Const(IRConst_U64( 1484f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U64))); 1485f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj break; 14860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Not32: 14870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 14880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U32))); 14890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Not16: 14919d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 14929d2e769a9368d2b22c32a4764a70e9da38769628sewardj ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U16)))); 14930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 14940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Not8: 14959d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 14969d2e769a9368d2b22c32a4764a70e9da38769628sewardj ~ (e->Iex.Unop.arg->Iex.Const.con->Ico.U8)))); 14970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 149839e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj 14990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Not1: 15000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U1( 15010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj notBool(e->Iex.Unop.arg->Iex.Const.con->Ico.U1))); 15020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1503d503a3284fea71d0be035536c995bdd9a96f91bdsewardj 1504291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj case Iop_64to8: { 1505291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1506291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj w64 &= 0xFFULL; 1507291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj e2 = IRExpr_Const(IRConst_U8( (UChar)w64 )); 1508291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj break; 1509291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj } 1510291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj case Iop_64to16: { 1511291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1512291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj w64 &= 0xFFFFULL; 1513e85bc40fb3dcbe32202239f042b180686765fdc3sewardj e2 = IRExpr_Const(IRConst_U16( (UShort)w64 )); 1514291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj break; 1515291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj } 15160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_64to32: { 15170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 15180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj w64 &= 0x00000000FFFFFFFFULL; 15190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( (UInt)w64 )); 15200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 15210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 15220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_64HIto32: { 15230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 15240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj w64 >>= 32; 15250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( (UInt)w64 )); 15260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 152739e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj } 1528b5710b8d435892c36da69c815db96f1db2feefc2sewardj case Iop_32Uto64: 1529b5710b8d435892c36da69c815db96f1db2feefc2sewardj e2 = IRExpr_Const(IRConst_U64( 1530b5710b8d435892c36da69c815db96f1db2feefc2sewardj 0xFFFFFFFFULL 1531b5710b8d435892c36da69c815db96f1db2feefc2sewardj & e->Iex.Unop.arg->Iex.Const.con->Ico.U32)); 1532b5710b8d435892c36da69c815db96f1db2feefc2sewardj break; 15337f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_16Sto64: { 1534108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 1535108e03fcb0a4ef42164235b1988aa540aa1e5298florian u64 <<= 48; 1536108e03fcb0a4ef42164235b1988aa540aa1e5298florian u64 = (Long)u64 >> 48; /* signed shift */ 1537108e03fcb0a4ef42164235b1988aa540aa1e5298florian e2 = IRExpr_Const(IRConst_U64(u64)); 15387f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 15397f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj } 1540287e9bb7ae95950d91c96eb7899c028a46edbed4sewardj case Iop_32Sto64: { 1541108e03fcb0a4ef42164235b1988aa540aa1e5298florian ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1542108e03fcb0a4ef42164235b1988aa540aa1e5298florian u64 <<= 32; 1543108e03fcb0a4ef42164235b1988aa540aa1e5298florian u64 = (Long)u64 >> 32; /* signed shift */ 1544108e03fcb0a4ef42164235b1988aa540aa1e5298florian e2 = IRExpr_Const(IRConst_U64(u64)); 1545287e9bb7ae95950d91c96eb7899c028a46edbed4sewardj break; 1546287e9bb7ae95950d91c96eb7899c028a46edbed4sewardj } 15477f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj 15487f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_16to8: { 15497f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj UShort w16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 15507f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj w16 &= 0xFF; 15517f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U8( (UChar)w16 )); 15527f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 15537f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj } 15547f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_16HIto8: { 15557f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj UShort w16 = e->Iex.Unop.arg->Iex.Const.con->Ico.U16; 15567f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj w16 >>= 8; 15577f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj w16 &= 0xFF; 15587f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U8( (UChar)w16 )); 15597f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 15607f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj } 15617f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj 15620033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_CmpNEZ8: 15630033ddccac6f90789fe2e78e86b8a649931d77b4sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 15640033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 0 != 15650033ddccac6f90789fe2e78e86b8a649931d77b4sewardj (0xFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U8) 15660033ddccac6f90789fe2e78e86b8a649931d77b4sewardj ))); 15670033ddccac6f90789fe2e78e86b8a649931d77b4sewardj break; 15680033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_CmpNEZ32: 15690033ddccac6f90789fe2e78e86b8a649931d77b4sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 15700033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 0 != 15710033ddccac6f90789fe2e78e86b8a649931d77b4sewardj (0xFFFFFFFF & e->Iex.Unop.arg->Iex.Const.con->Ico.U32) 15720033ddccac6f90789fe2e78e86b8a649931d77b4sewardj ))); 15730033ddccac6f90789fe2e78e86b8a649931d77b4sewardj break; 15740033ddccac6f90789fe2e78e86b8a649931d77b4sewardj case Iop_CmpNEZ64: 15750033ddccac6f90789fe2e78e86b8a649931d77b4sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 15760033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 0ULL != e->Iex.Unop.arg->Iex.Const.con->Ico.U64 15770033ddccac6f90789fe2e78e86b8a649931d77b4sewardj ))); 15780033ddccac6f90789fe2e78e86b8a649931d77b4sewardj break; 15790033ddccac6f90789fe2e78e86b8a649931d77b4sewardj 1580eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpwNEZ32: { 1581eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj UInt w32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1582eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (w32 == 0) 1583eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const(IRConst_U32( 0 )); 1584eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj else 1585eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const(IRConst_U32( 0xFFFFFFFF )); 1586eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 1587eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 1588eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpwNEZ64: { 1589eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj ULong w64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1590eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (w64 == 0) 1591eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const(IRConst_U64( 0 )); 1592eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj else 1593eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const(IRConst_U64( 0xFFFFFFFFFFFFFFFFULL )); 1594eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 1595eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 1596eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 1597eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_Left32: { 1598eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 1599eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj Int s32 = (Int)(u32 & 0xFFFFFFFF); 1600eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj s32 = (s32 | (-s32)); 1601eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const( IRConst_U32( (UInt)s32 )); 1602eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 1603eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 1604eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 1605eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_Left64: { 1606eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 1607eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj Long s64 = (Long)u64; 1608eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj s64 = (s64 | (-s64)); 1609eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj e2 = IRExpr_Const( IRConst_U64( (ULong)s64 )); 1610eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 1611eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 1612eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 16134cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj case Iop_Clz32: { 16144cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 16154cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj if (u32 != 0) 16164cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj e2 = IRExpr_Const(IRConst_U32(fold_Clz32(u32))); 16174cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj break; 16184cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj } 16194cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj case Iop_Clz64: { 16204cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 16214cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj if (u64 != 0ULL) 16224cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj e2 = IRExpr_Const(IRConst_U64(fold_Clz64(u64))); 16234cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj break; 16244cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj } 16254cba9f4d2f3b9999586c56fc8507d50df8607a74sewardj 16264a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj /* For these vector ones, can't fold all cases, but at least 16274a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj do the most obvious one. Could do better here using 16284a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj summarise/desummarise of vector constants, but too 16294a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj difficult to verify; hence just handle the zero cases. */ 16304a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_32UtoV128: { 16314a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj UInt u32 = e->Iex.Unop.arg->Iex.Const.con->Ico.U32; 16324a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == u32) { 16334a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128(0x0000)); 16344a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 16354a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 16364a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16374a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 16384a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16394a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_V128to64: { 16404a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj UShort v128 = e->Iex.Unop.arg->Iex.Const.con->Ico.V128; 16414a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == ((v128 >> 0) & 0xFF)) { 16424a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_U64(0)); 16434a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 16444a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 16454a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16464a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 16474a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16484a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_V128HIto64: { 16494a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj UShort v128 = e->Iex.Unop.arg->Iex.Const.con->Ico.V128; 16504a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == ((v128 >> 8) & 0xFF)) { 16514a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_U64(0)); 16524a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 16534a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 16544a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16554a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 16564a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16574a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_64UtoV128: { 16584a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ULong u64 = e->Iex.Unop.arg->Iex.Const.con->Ico.U64; 16594a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == u64) { 16604a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128(0x0000)); 16614a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 16624a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 16634a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16644a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 16654a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 16664a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj 1667ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj /* Even stupider (although still correct ..) */ 1668ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj case Iop_V256to64_0: case Iop_V256to64_1: 1669ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj case Iop_V256to64_2: case Iop_V256to64_3: { 1670ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj UInt v256 = e->Iex.Unop.arg->Iex.Const.con->Ico.V256; 1671ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj if (v256 == 0x00000000) { 1672ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj e2 = IRExpr_Const(IRConst_U64(0)); 1673ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj } else { 1674ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj goto unhandled; 1675ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj } 1676ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj break; 1677ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj } 1678ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj 1679fbe569d562acd250611c7d0491485bea1a8159cfsewardj case Iop_ZeroHI64ofV128: { 1680fbe569d562acd250611c7d0491485bea1a8159cfsewardj /* Could do better here -- only need to look at the bottom 64 bits 1681fbe569d562acd250611c7d0491485bea1a8159cfsewardj of the argument, really. */ 1682fbe569d562acd250611c7d0491485bea1a8159cfsewardj UShort v128 = e->Iex.Unop.arg->Iex.Const.con->Ico.V128; 1683fbe569d562acd250611c7d0491485bea1a8159cfsewardj if (v128 == 0x0000) { 1684fbe569d562acd250611c7d0491485bea1a8159cfsewardj e2 = IRExpr_Const(IRConst_V128(0x0000)); 1685fbe569d562acd250611c7d0491485bea1a8159cfsewardj } else { 1686fbe569d562acd250611c7d0491485bea1a8159cfsewardj goto unhandled; 1687fbe569d562acd250611c7d0491485bea1a8159cfsewardj } 1688fbe569d562acd250611c7d0491485bea1a8159cfsewardj break; 1689fbe569d562acd250611c7d0491485bea1a8159cfsewardj } 1690fbe569d562acd250611c7d0491485bea1a8159cfsewardj 16910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 16920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto unhandled; 169339e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj } 1694708417d56d1798ffd62a05b7932da47cdc3d3337florian } 1695708417d56d1798ffd62a05b7932da47cdc3d3337florian break; 1696d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1697708417d56d1798ffd62a05b7932da47cdc3d3337florian case Iex_Binop: 1698708417d56d1798ffd62a05b7932da47cdc3d3337florian /* BINARY ops */ 16990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e->Iex.Binop.arg1->tag == Iex_Const 17000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && e->Iex.Binop.arg2->tag == Iex_Const) { 17010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* cases where both args are consts */ 17020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (e->Iex.Binop.op) { 1703d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1704855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Or -- */ 17050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Or8: 17069d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 17070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 17089d2e769a9368d2b22c32a4764a70e9da38769628sewardj | e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 17090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 17100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Or16: 17119d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 17120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 17139d2e769a9368d2b22c32a4764a70e9da38769628sewardj | e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 17140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 17150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Or32: 17160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 17170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 17180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj | e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 17190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1720f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj case Iop_Or64: 1721f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj e2 = IRExpr_Const(IRConst_U64( 1722f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1723f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj | e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1724f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj break; 17254a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_OrV128: 17264a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128( 17274a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 17284a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj | e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 17294a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 1730d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1731855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Xor -- */ 17320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Xor8: 17339d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 17340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 17359d2e769a9368d2b22c32a4764a70e9da38769628sewardj ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 17360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 173782c9f2fc94b8b7d741ac781656fb918507f02bf4sewardj case Iop_Xor16: 1738c7c098ffb5170559fa21b341ced757e6e347f16esewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 173982c9f2fc94b8b7d741ac781656fb918507f02bf4sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 1740c7c098ffb5170559fa21b341ced757e6e347f16esewardj ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 174182c9f2fc94b8b7d741ac781656fb918507f02bf4sewardj break; 1742855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Xor32: 1743855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U32( 1744855dc72bbd008ca475ba5853c67b0b173096de1asewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1745855dc72bbd008ca475ba5853c67b0b173096de1asewardj ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1746855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 1747f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj case Iop_Xor64: 1748f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj e2 = IRExpr_Const(IRConst_U64( 1749f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1750f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1751f057afbef0dd5dd94a9702422ab8192565bd0f96sewardj break; 17524a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_XorV128: 17534a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128( 17544a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 17554a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ^ e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 17564a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 1757855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1758855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- And -- */ 17590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_And8: 17609d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 17610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 17629d2e769a9368d2b22c32a4764a70e9da38769628sewardj & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 17630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 17647f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_And16: 17657f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U16(toUShort( 17667f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U16 17677f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj & e->Iex.Binop.arg2->Iex.Const.con->Ico.U16)))); 17687f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 1769855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_And32: 17700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 17710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1772855dc72bbd008ca475ba5853c67b0b173096de1asewardj & e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 17730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1774855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_And64: 177570a8ddfd89fbf0b0dc7b97e8bce9897cf31ba003sewardj e2 = IRExpr_Const(IRConst_U64( 177670a8ddfd89fbf0b0dc7b97e8bce9897cf31ba003sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1777855dc72bbd008ca475ba5853c67b0b173096de1asewardj & e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 177870a8ddfd89fbf0b0dc7b97e8bce9897cf31ba003sewardj break; 17794a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_AndV128: 17804a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128( 17814a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.V128 17824a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj & e->Iex.Binop.arg2->Iex.Const.con->Ico.V128))); 17834a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 1784c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj 1785855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Add -- */ 1786855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Add8: 1787855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 1788855dc72bbd008ca475ba5853c67b0b173096de1asewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1789855dc72bbd008ca475ba5853c67b0b173096de1asewardj + e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 1790855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 17910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Add32: 17920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 17930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 17940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj + e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 17950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1796c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj case Iop_Add64: 1797c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj e2 = IRExpr_Const(IRConst_U64( 1798c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1799c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj + e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1800c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj break; 1801c2bcb6f78b7fc9066befa79aeaee57f82a087545sewardj 1802855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Sub -- */ 1803855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Sub8: 1804855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U8(toUChar( 1805855dc72bbd008ca475ba5853c67b0b173096de1asewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U8 1806855dc72bbd008ca475ba5853c67b0b173096de1asewardj - e->Iex.Binop.arg2->Iex.Const.con->Ico.U8)))); 18070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1808855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Sub32: 18090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 18100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 1811855dc72bbd008ca475ba5853c67b0b173096de1asewardj - e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 1812855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 1813855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Sub64: 1814855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U64( 1815855dc72bbd008ca475ba5853c67b0b173096de1asewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1816855dc72bbd008ca475ba5853c67b0b173096de1asewardj - e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 18170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1818575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 1819478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj /* -- Max32U -- */ 1820478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj case Iop_Max32U: { 1821478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 1822478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 1823478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj UInt res = u32a > u32b ? u32a : u32b; 1824478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj e2 = IRExpr_Const(IRConst_U32(res)); 1825478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj break; 1826478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj } 1827478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj 1828855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Mul -- */ 18290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Mul32: 18300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 18310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 18320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))); 18330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1834a34c071b549860710128356b8428ae4e368ef089sewardj case Iop_Mul64: 1835a34c071b549860710128356b8428ae4e368ef089sewardj e2 = IRExpr_Const(IRConst_U64( 1836a34c071b549860710128356b8428ae4e368ef089sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1837a34c071b549860710128356b8428ae4e368ef089sewardj * e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))); 1838a34c071b549860710128356b8428ae4e368ef089sewardj break; 1839a34c071b549860710128356b8428ae4e368ef089sewardj 1840ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj case Iop_MullS32: { 1841ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj /* very paranoid */ 1842ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 1843ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 1844ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj Int s32a = (Int)u32a; 1845ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj Int s32b = (Int)u32b; 1846ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj Long s64a = (Long)s32a; 1847ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj Long s64b = (Long)s32b; 1848ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj Long sres = s64a * s64b; 1849ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj ULong ures = (ULong)sres; 1850ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj e2 = IRExpr_Const(IRConst_U64(ures)); 1851ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj break; 1852ea6bccb0dbc7a94b3475b951f5ebda3155a06f38sewardj } 1853b095fba59bf2a23d574342f510d920127bda2c73sewardj 1854855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Shl -- */ 18550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Shl32: 18560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 18570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 18580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (shift >= 0 && shift <= 31) 18590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32( 18600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 18610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj << shift))); 18620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1863b095fba59bf2a23d574342f510d920127bda2c73sewardj case Iop_Shl64: 1864b095fba59bf2a23d574342f510d920127bda2c73sewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1865b095fba59bf2a23d574342f510d920127bda2c73sewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1866b095fba59bf2a23d574342f510d920127bda2c73sewardj if (shift >= 0 && shift <= 63) 1867b095fba59bf2a23d574342f510d920127bda2c73sewardj e2 = IRExpr_Const(IRConst_U64( 1868b095fba59bf2a23d574342f510d920127bda2c73sewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1869b095fba59bf2a23d574342f510d920127bda2c73sewardj << shift))); 1870b095fba59bf2a23d574342f510d920127bda2c73sewardj break; 1871b095fba59bf2a23d574342f510d920127bda2c73sewardj 1872855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Sar -- */ 18730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Sar32: { 18740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* paranoid ... */ 18750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /*signed*/ Int s32; 18760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 18770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj s32 = (Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32); 18780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 18790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (shift >= 0 && shift <= 31) { 18800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj s32 >>=/*signed*/ shift; 18810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U32((UInt)s32)); 18820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 18830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 18840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 1885855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_Sar64: { 1886855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* paranoid ... */ 1887855dc72bbd008ca475ba5853c67b0b173096de1asewardj /*signed*/ Long s64; 1888855dc72bbd008ca475ba5853c67b0b173096de1asewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 1889855dc72bbd008ca475ba5853c67b0b173096de1asewardj s64 = (Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64); 1890855dc72bbd008ca475ba5853c67b0b173096de1asewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 1891855dc72bbd008ca475ba5853c67b0b173096de1asewardj if (shift >= 0 && shift <= 63) { 1892855dc72bbd008ca475ba5853c67b0b173096de1asewardj s64 >>=/*signed*/ shift; 1893855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U64((ULong)s64)); 1894855dc72bbd008ca475ba5853c67b0b173096de1asewardj } 1895855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 1896855dc72bbd008ca475ba5853c67b0b173096de1asewardj } 1897855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1898855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- Shr -- */ 18990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_Shr32: { 19000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* paranoid ... */ 19014add714eb0f3a8edb50c826a12d29912df75a7a8sewardj /*unsigned*/ UInt u32; 19020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 19034add714eb0f3a8edb50c826a12d29912df75a7a8sewardj u32 = (UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32); 19040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 19050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (shift >= 0 && shift <= 31) { 19064add714eb0f3a8edb50c826a12d29912df75a7a8sewardj u32 >>=/*unsigned*/ shift; 19074add714eb0f3a8edb50c826a12d29912df75a7a8sewardj e2 = IRExpr_Const(IRConst_U32(u32)); 19084add714eb0f3a8edb50c826a12d29912df75a7a8sewardj } 19094add714eb0f3a8edb50c826a12d29912df75a7a8sewardj break; 19104add714eb0f3a8edb50c826a12d29912df75a7a8sewardj } 19114add714eb0f3a8edb50c826a12d29912df75a7a8sewardj case Iop_Shr64: { 19124add714eb0f3a8edb50c826a12d29912df75a7a8sewardj /* paranoid ... */ 19134add714eb0f3a8edb50c826a12d29912df75a7a8sewardj /*unsigned*/ ULong u64; 19144add714eb0f3a8edb50c826a12d29912df75a7a8sewardj vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); 19154add714eb0f3a8edb50c826a12d29912df75a7a8sewardj u64 = (ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64); 19164add714eb0f3a8edb50c826a12d29912df75a7a8sewardj shift = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U8); 19174add714eb0f3a8edb50c826a12d29912df75a7a8sewardj if (shift >= 0 && shift <= 63) { 19184add714eb0f3a8edb50c826a12d29912df75a7a8sewardj u64 >>=/*unsigned*/ shift; 19194add714eb0f3a8edb50c826a12d29912df75a7a8sewardj e2 = IRExpr_Const(IRConst_U64(u64)); 19200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 19210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 19220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 1923855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1924855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpEQ -- */ 19250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpEQ32: 19269d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 19289d2e769a9368d2b22c32a4764a70e9da38769628sewardj == e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))); 19290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1930855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_CmpEQ64: 1931855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U1(toBool( 1932855dc72bbd008ca475ba5853c67b0b173096de1asewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 1933855dc72bbd008ca475ba5853c67b0b173096de1asewardj == e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)))); 1934855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 1935855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1936855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpNE -- */ 1937855dc72bbd008ca475ba5853c67b0b173096de1asewardj case Iop_CmpNE8: 1938e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_CasCmpNE8: 1939e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_ExpCmpNE8: 1940855dc72bbd008ca475ba5853c67b0b173096de1asewardj e2 = IRExpr_Const(IRConst_U1(toBool( 1941855dc72bbd008ca475ba5853c67b0b173096de1asewardj ((0xFF & e->Iex.Binop.arg1->Iex.Const.con->Ico.U8) 1942855dc72bbd008ca475ba5853c67b0b173096de1asewardj != (0xFF & e->Iex.Binop.arg2->Iex.Const.con->Ico.U8))))); 1943855dc72bbd008ca475ba5853c67b0b173096de1asewardj break; 19440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpNE32: 1945e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_CasCmpNE32: 1946e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_ExpCmpNE32: 19479d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 19499d2e769a9368d2b22c32a4764a70e9da38769628sewardj != e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)))); 19500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 19510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpNE64: 1952e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_CasCmpNE64: 1953e13074c2c1321d069fb95806bdce64f9a3512341sewardj case Iop_ExpCmpNE64: 19549d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (e->Iex.Binop.arg1->Iex.Const.con->Ico.U64 19569d2e769a9368d2b22c32a4764a70e9da38769628sewardj != e->Iex.Binop.arg2->Iex.Const.con->Ico.U64)))); 19570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 1958d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1959855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpLEU -- */ 19600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpLE32U: 19619d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 19639d2e769a9368d2b22c32a4764a70e9da38769628sewardj <= (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 19640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 19657f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_CmpLE64U: 19667f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19677f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj ((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 19687f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj <= (ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 19697f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 1970855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1971855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpLES -- */ 19720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpLE32S: 19739d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 19759d2e769a9368d2b22c32a4764a70e9da38769628sewardj <= (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 19760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 19777f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_CmpLE64S: 19787f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19797f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj ((Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 19807f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj <= (Long)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 19817f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 1982d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 1983855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpLTS -- */ 19840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpLT32S: 19859d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ((Int)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 19879d2e769a9368d2b22c32a4764a70e9da38769628sewardj < (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 19880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 19897f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_CmpLT64S: 19907f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19917f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj ((Long)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 19927f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj < (Long)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 19937f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 1994855dc72bbd008ca475ba5853c67b0b173096de1asewardj 1995855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- CmpLTU -- */ 19960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_CmpLT32U: 19979d2e769a9368d2b22c32a4764a70e9da38769628sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 19980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ((UInt)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U32) 19999d2e769a9368d2b22c32a4764a70e9da38769628sewardj < (UInt)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32))))); 20000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 20017f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj case Iop_CmpLT64U: 20027f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj e2 = IRExpr_Const(IRConst_U1(toBool( 20037f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj ((ULong)(e->Iex.Binop.arg1->Iex.Const.con->Ico.U64) 20047f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj < (ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U64))))); 20057f6330dbf0608dcc395ec49e66c25f7ad03a8c60sewardj break; 20062963239357452b96dbe6de1b3f8b626ea3305780sewardj 2007b51f0f4f33256638ed953156a2635aa739b232f1sewardj /* -- CmpORD -- */ 2008b51f0f4f33256638ed953156a2635aa739b232f1sewardj case Iop_CmpORD32S: { 2009b51f0f4f33256638ed953156a2635aa739b232f1sewardj /* very paranoid */ 2010b51f0f4f33256638ed953156a2635aa739b232f1sewardj UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32; 2011b51f0f4f33256638ed953156a2635aa739b232f1sewardj UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32; 2012b51f0f4f33256638ed953156a2635aa739b232f1sewardj Int s32a = (Int)u32a; 2013b51f0f4f33256638ed953156a2635aa739b232f1sewardj Int s32b = (Int)u32b; 2014b51f0f4f33256638ed953156a2635aa739b232f1sewardj Int r = 0x2; /* EQ */ 2015b51f0f4f33256638ed953156a2635aa739b232f1sewardj if (s32a < s32b) { 2016b51f0f4f33256638ed953156a2635aa739b232f1sewardj r = 0x8; /* LT */ 2017b51f0f4f33256638ed953156a2635aa739b232f1sewardj } 2018b51f0f4f33256638ed953156a2635aa739b232f1sewardj else if (s32a > s32b) { 2019b51f0f4f33256638ed953156a2635aa739b232f1sewardj r = 0x4; /* GT */ 2020b51f0f4f33256638ed953156a2635aa739b232f1sewardj } 2021b51f0f4f33256638ed953156a2635aa739b232f1sewardj e2 = IRExpr_Const(IRConst_U32(r)); 2022b51f0f4f33256638ed953156a2635aa739b232f1sewardj break; 2023b51f0f4f33256638ed953156a2635aa739b232f1sewardj } 2024b51f0f4f33256638ed953156a2635aa739b232f1sewardj 2025855dc72bbd008ca475ba5853c67b0b173096de1asewardj /* -- nHLto2n -- */ 20260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iop_32HLto64: 20270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e2 = IRExpr_Const(IRConst_U64( 20284a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj (((ULong)(e->Iex.Binop.arg1 20294a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ->Iex.Const.con->Ico.U32)) << 32) 20300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj | ((ULong)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) 20310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj )); 20320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 20333bc8a59c12554ebd3abdb04c2417e0077054f936sewardj case Iop_64HLto128: 20343bc8a59c12554ebd3abdb04c2417e0077054f936sewardj /* We can't fold this, because there is no way to 20353bc8a59c12554ebd3abdb04c2417e0077054f936sewardj express he result in IR, but at least pretend to 20363bc8a59c12554ebd3abdb04c2417e0077054f936sewardj handle it, so as to stop getting blasted with 20373bc8a59c12554ebd3abdb04c2417e0077054f936sewardj no-rule-for-this-primop messages. */ 20383bc8a59c12554ebd3abdb04c2417e0077054f936sewardj break; 20394a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj /* For this vector one, can't fold all cases, but at 20404a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj least do the most obvious one. Could do better here 20414a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj using summarise/desummarise of vector constants, but 20424a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj too difficult to verify; hence just handle the zero 20434a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj cases. */ 20444a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_64HLtoV128: { 20454a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ULong argHi = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64; 20464a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ULong argLo = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64; 20474a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == argHi && 0 == argLo) { 20484a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128(0)); 20494a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 20504a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 20514a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 20524a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 20534a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 20549571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj /* Same reasoning for the 256-bit version. */ 20559571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj case Iop_V128HLtoV256: { 20569571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj IRExpr* argHi = e->Iex.Binop.arg1; 20579571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj IRExpr* argLo = e->Iex.Binop.arg2; 20589571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (isZeroV128(argHi) && isZeroV128(argLo)) { 20599571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj e2 = IRExpr_Const(IRConst_V256(0)); 20609571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } else { 20619571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj goto unhandled; 20629571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 20639571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj break; 20649571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 20654a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj 20664a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj /* -- V128 stuff -- */ 20674a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_InterleaveLO8x16: { 20684a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj /* This turns up a lot in Memcheck instrumentation of 20694a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj Icc generated code. I don't know why. */ 20704a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj UShort arg1 = e->Iex.Binop.arg1->Iex.Const.con->Ico.V128; 20714a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj UShort arg2 = e->Iex.Binop.arg2->Iex.Const.con->Ico.V128; 20724a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj if (0 == arg1 && 0 == arg2) { 20734a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj e2 = IRExpr_Const(IRConst_V128(0)); 20744a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } else { 20754a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj goto unhandled; 20764a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 20774a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj break; 20784a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj } 2079855dc72bbd008ca475ba5853c67b0b173096de1asewardj 20800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 20810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto unhandled; 20820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2083f0e431671cb877601c2f2e551f42246469b4ee62sewardj 20840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 2085d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 20860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* other cases (identities, etc) */ 208764d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj switch (e->Iex.Binop.op) { 2088f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2089f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Shl32: 2090f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Shl64: 2091f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Shr64: 2092b979d7a9fd0fd7cb3b71de211584ea662f4fa140sewardj case Iop_Sar64: 2093b979d7a9fd0fd7cb3b71de211584ea662f4fa140sewardj /* Shl32/Shl64/Shr64/Sar64(x,0) ==> x */ 2094f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg2)) { 2095f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2096f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2097f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2098f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Shl32/Shl64/Shr64(0,x) ==> 0 */ 2099f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg1)) { 2100f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2101f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2102f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2103f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2104f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2105b979d7a9fd0fd7cb3b71de211584ea662f4fa140sewardj case Iop_Sar32: 2106f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Shr32: 2107b979d7a9fd0fd7cb3b71de211584ea662f4fa140sewardj /* Shr32/Sar32(x,0) ==> x */ 2108f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg2)) { 2109f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2110f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2111f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2112f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2113f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2114f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Or8: 2115f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Or16: 2116f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Or32: 2117f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Or64: 211864d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_Max32U: 2119cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj /* Or8/Or16/Or32/Or64/Max32U(x,0) ==> x */ 2120f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg2)) { 2121f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2122f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2123f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2124cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj /* Or8/Or16/Or32/Or64/Max32U(0,x) ==> x */ 2125f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg1)) { 2126f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg2; 2127f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2128f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2129cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj /* Or8/Or16/Or32/Or64/Max32U(x,1---1b) ==> 1---1b */ 2130cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj /* Or8/Or16/Or32/Or64/Max32U(1---1b,x) ==> 1---1b */ 2131cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj if (isOnesU(e->Iex.Binop.arg1) || isOnesU(e->Iex.Binop.arg2)) { 2132cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj e2 = mkOnesOfPrimopResultType(e->Iex.Binop.op); 2133cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj break; 2134cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj } 2135cf4be4a70cb7393839b68fad19e3660e2c053b57sewardj /* Or8/Or16/Or32/Or64/Max32U(t,t) ==> t, for some IRTemp t */ 2136cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 213764d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj e2 = e->Iex.Binop.arg1; 2138f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2139f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 214064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 2141f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2142f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Add8: 2143f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Add8(t,t) ==> t << 1. 2144f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian Memcheck doesn't understand that 2145f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian x+x produces a defined least significant bit, and it seems 2146f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian simplest just to get rid of the problem by rewriting it 2147f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian out, since the opportunity to do so exists. */ 2148cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2149f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = IRExpr_Binop(Iop_Shl8, e->Iex.Binop.arg1, 2150f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian IRExpr_Const(IRConst_U8(1))); 2151f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2152f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 215364d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 2154d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 2155f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* NB no Add16(t,t) case yet as no known test case exists */ 2156f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2157f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Add32: 2158f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Add64: 2159f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Add32/Add64(x,0) ==> x */ 2160f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg2)) { 2161f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2162f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2163f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2164f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Add32/Add64(0,x) ==> x */ 2165f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian if (isZeroU(e->Iex.Binop.arg1)) { 2166f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg2; 2167f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2168f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2169f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Add32/Add64(t,t) ==> t << 1. Same rationale as for Add8. */ 2170cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 21716399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e2 = IRExpr_Binop( 21726399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e->Iex.Binop.op == Iop_Add32 ? Iop_Shl32 : Iop_Shl64, 21736399f81e98cd8c7fbd55255c67f051a0a1873658sewardj e->Iex.Binop.arg1, IRExpr_Const(IRConst_U8(1))); 2174f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2175f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2176f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2177f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 21781beb4330bdbd49e1a162734d5eb1b2ec6f6cbf04sewardj case Iop_Sub32: 2179f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Sub64: 21801beb4330bdbd49e1a162734d5eb1b2ec6f6cbf04sewardj /* Sub32/Sub64(x,0) ==> x */ 21811beb4330bdbd49e1a162734d5eb1b2ec6f6cbf04sewardj if (isZeroU(e->Iex.Binop.arg2)) { 2182f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2183f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2184f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 21851beb4330bdbd49e1a162734d5eb1b2ec6f6cbf04sewardj /* Sub32/Sub64(t,t) ==> 0, for some IRTemp t */ 2186cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2187f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2188f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2189f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2190f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 219136a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj case Iop_Sub8x16: 219236a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj /* Sub8x16(x,0) ==> x */ 219336a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj if (isZeroV128(e->Iex.Binop.arg2)) { 219436a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj e2 = e->Iex.Binop.arg1; 219536a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj break; 219636a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj } 219736a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj break; 2198f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 21992782d2143d385935418ce42aa5754fd6a97e9692florian case Iop_And8: 22002782d2143d385935418ce42aa5754fd6a97e9692florian case Iop_And16: 2201f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_And32: 22022782d2143d385935418ce42aa5754fd6a97e9692florian case Iop_And64: 22032782d2143d385935418ce42aa5754fd6a97e9692florian /* And8/And16/And32/And64(x,1---1b) ==> x */ 220455ce7b748cd0c8534865844f219685fdb8e96e59florian if (isOnesU(e->Iex.Binop.arg2)) { 2205f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2206f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2207f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 22082782d2143d385935418ce42aa5754fd6a97e9692florian /* And8/And16/And32/And64(1---1b,x) ==> x */ 22092782d2143d385935418ce42aa5754fd6a97e9692florian if (isOnesU(e->Iex.Binop.arg1)) { 22102782d2143d385935418ce42aa5754fd6a97e9692florian e2 = e->Iex.Binop.arg2; 22112782d2143d385935418ce42aa5754fd6a97e9692florian break; 22122782d2143d385935418ce42aa5754fd6a97e9692florian } 22132782d2143d385935418ce42aa5754fd6a97e9692florian /* And8/And16/And32/And64(x,0) ==> 0 */ 221455ce7b748cd0c8534865844f219685fdb8e96e59florian if (isZeroU(e->Iex.Binop.arg2)) { 2215f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg2; 2216f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2217f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 22182782d2143d385935418ce42aa5754fd6a97e9692florian /* And8/And16/And32/And64(0,x) ==> 0 */ 221955ce7b748cd0c8534865844f219685fdb8e96e59florian if (isZeroU(e->Iex.Binop.arg1)) { 2220f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2221f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2222f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 22232782d2143d385935418ce42aa5754fd6a97e9692florian /* And8/And16/And32/And64(t,t) ==> t, for some IRTemp t */ 2224cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2225f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2226f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2227f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2228f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2229f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 22304a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_AndV128: 22314a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_AndV256: 223255ce7b748cd0c8534865844f219685fdb8e96e59florian /* And8/And16/AndV128/AndV256(t,t) 22334a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ==> t, for some IRTemp t */ 2234cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2235f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2236f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2237f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 223836a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj /* Deal with either arg zero. Could handle other And 223936a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj cases here too. */ 22401b7c4719bc445c8e71230e58e62050d67aaf0109florian if (e->Iex.Binop.op == Iop_AndV256 22411b7c4719bc445c8e71230e58e62050d67aaf0109florian && (isZeroV256(e->Iex.Binop.arg1) 22421b7c4719bc445c8e71230e58e62050d67aaf0109florian || isZeroV256(e->Iex.Binop.arg2))) { 2243bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2244bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj break; 224536a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj } else if (e->Iex.Binop.op == Iop_AndV128 224636a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj && (isZeroV128(e->Iex.Binop.arg1) 224736a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj || isZeroV128(e->Iex.Binop.arg2))) { 224836a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 224936a911a8167a49ed3b3c5da4cd8344dfe18acf1dsewardj break; 2250bbcf188f6ae64a44fb31414eb9e1a738b4befcc0sewardj } 2251f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2252f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2253f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_OrV128: 22544a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj case Iop_OrV256: 22554a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj /* V128/V256(t,t) ==> t, for some IRTemp t */ 2256cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2257f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = e->Iex.Binop.arg1; 2258f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2259f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 22609571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj /* OrV128(t,0) ==> t */ 22619571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (e->Iex.Binop.op == Iop_OrV128) { 22629571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (isZeroV128(e->Iex.Binop.arg2)) { 22639571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj e2 = e->Iex.Binop.arg1; 22649571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj break; 22659571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 22669571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (isZeroV128(e->Iex.Binop.arg1)) { 22679571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj e2 = e->Iex.Binop.arg2; 22689571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj break; 22699571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 22709571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 22719571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj /* OrV256(t,0) ==> t */ 22729571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (e->Iex.Binop.op == Iop_OrV256) { 22739571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj if (isZeroV256(e->Iex.Binop.arg2)) { 22749571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj e2 = e->Iex.Binop.arg1; 22759571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj break; 22769571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 22779571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj //Disabled because there's no known test case right now. 22789571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj //if (isZeroV256(e->Iex.Binop.arg1)) { 22799571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj // e2 = e->Iex.Binop.arg2; 22809571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj // break; 22819571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj //} 22829571dc05739e7980539cfd9dbc4e9ca19324e6d6sewardj } 2283f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2284f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2285f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Xor8: 2286f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Xor16: 2287f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Xor32: 2288f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian case Iop_Xor64: 228964d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_XorV128: 229070dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case Iop_XorV256: 2291f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian /* Xor8/16/32/64/V128(t,t) ==> 0, for some IRTemp t */ 2292cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 229364d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2294f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2295f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2296b01ff4034e82ba4e57ab417af9a79742dc522934sewardj /* XorV128(t,0) ==> t */ 2297b01ff4034e82ba4e57ab417af9a79742dc522934sewardj if (e->Iex.Binop.op == Iop_XorV128) { 2298b01ff4034e82ba4e57ab417af9a79742dc522934sewardj if (isZeroV128(e->Iex.Binop.arg2)) { 2299b01ff4034e82ba4e57ab417af9a79742dc522934sewardj e2 = e->Iex.Binop.arg1; 2300b01ff4034e82ba4e57ab417af9a79742dc522934sewardj break; 2301b01ff4034e82ba4e57ab417af9a79742dc522934sewardj } 2302b01ff4034e82ba4e57ab417af9a79742dc522934sewardj //Disabled because there's no known test case right now. 2303b01ff4034e82ba4e57ab417af9a79742dc522934sewardj //if (isZeroV128(e->Iex.Binop.arg1)) { 2304b01ff4034e82ba4e57ab417af9a79742dc522934sewardj // e2 = e->Iex.Binop.arg2; 2305b01ff4034e82ba4e57ab417af9a79742dc522934sewardj // break; 2306b01ff4034e82ba4e57ab417af9a79742dc522934sewardj //} 23079e2a0080120557075fcf84237bd4cf7f257911e9sewardj } else { 23089e2a0080120557075fcf84237bd4cf7f257911e9sewardj /* Xor8/16/32/64(0,t) ==> t */ 23099e2a0080120557075fcf84237bd4cf7f257911e9sewardj if (isZeroU(e->Iex.Binop.arg1)) { 23109e2a0080120557075fcf84237bd4cf7f257911e9sewardj e2 = e->Iex.Binop.arg2; 23119e2a0080120557075fcf84237bd4cf7f257911e9sewardj break; 23129e2a0080120557075fcf84237bd4cf7f257911e9sewardj } 23139e2a0080120557075fcf84237bd4cf7f257911e9sewardj /* Xor8/16/32/64(t,0) ==> t */ 23149e2a0080120557075fcf84237bd4cf7f257911e9sewardj if (isZeroU(e->Iex.Binop.arg2)) { 23159e2a0080120557075fcf84237bd4cf7f257911e9sewardj e2 = e->Iex.Binop.arg1; 23169e2a0080120557075fcf84237bd4cf7f257911e9sewardj break; 23179e2a0080120557075fcf84237bd4cf7f257911e9sewardj } 2318b01ff4034e82ba4e57ab417af9a79742dc522934sewardj } 231964d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 2320f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 2321a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj case Iop_CmpNE32: 23221beb4330bdbd49e1a162734d5eb1b2ec6f6cbf04sewardj /* CmpNE32(t,t) ==> 0, for some IRTemp t */ 2323cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 2324f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); 2325f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2326f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 2327009230b9758291b594e60d7c0243a73d53e81854sewardj /* CmpNE32(1Uto32(b), 0) ==> b */ 2328009230b9758291b594e60d7c0243a73d53e81854sewardj if (isZeroU32(e->Iex.Binop.arg2)) { 2329009230b9758291b594e60d7c0243a73d53e81854sewardj IRExpr* a1 = chase(env, e->Iex.Binop.arg1); 2330009230b9758291b594e60d7c0243a73d53e81854sewardj if (a1 && a1->tag == Iex_Unop 2331009230b9758291b594e60d7c0243a73d53e81854sewardj && a1->Iex.Unop.op == Iop_1Uto32) { 2332009230b9758291b594e60d7c0243a73d53e81854sewardj e2 = a1->Iex.Unop.arg; 2333009230b9758291b594e60d7c0243a73d53e81854sewardj break; 2334009230b9758291b594e60d7c0243a73d53e81854sewardj } 2335009230b9758291b594e60d7c0243a73d53e81854sewardj } 233664d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 233764d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj 2338a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj case Iop_CmpEQ32: 233964d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ64: 234064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ8x8: 234164d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj case Iop_CmpEQ8x16: 2342899d1838d6fd60b141a3d808b02dc04be5901681sewardj case Iop_CmpEQ16x8: 2343ffccf2be3406c1344706d0fe7ae57e1c3998e6cdsewardj case Iop_CmpEQ32x4: 2344cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 234564d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj e2 = mkOnesOfPrimopResultType(e->Iex.Binop.op); 2346f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian break; 2347f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian } 234864d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 2349f6402ab3a43ec0eb821b4612a9bc8bae34f04dfaflorian 235064d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj default: 235164d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj break; 23520033ddccac6f90789fe2e78e86b8a649931d77b4sewardj } 2353d721703a7a904a66c49d0e6318c184d0076b40b0sewardj } 2354708417d56d1798ffd62a05b7932da47cdc3d3337florian break; 2355708417d56d1798ffd62a05b7932da47cdc3d3337florian 235699dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 235799dd03e04a6914d90d5fee727d61d76905334becflorian /* ITE */ 23586c299f3acab617581ea504e45fbb6cab24c2b29fsewardj /* is the discriminant is a constant? */ 235999dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.cond->tag == Iex_Const) { 23606c299f3acab617581ea504e45fbb6cab24c2b29fsewardj /* assured us by the IR type rules */ 236199dd03e04a6914d90d5fee727d61d76905334becflorian vassert(e->Iex.ITE.cond->Iex.Const.con->tag == Ico_U1); 236299dd03e04a6914d90d5fee727d61d76905334becflorian e2 = e->Iex.ITE.cond->Iex.Const.con->Ico.U1 236399dd03e04a6914d90d5fee727d61d76905334becflorian ? e->Iex.ITE.iftrue : e->Iex.ITE.iffalse; 23646c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 23656c299f3acab617581ea504e45fbb6cab24c2b29fsewardj else 23666c299f3acab617581ea504e45fbb6cab24c2b29fsewardj /* are the arms identical? (pretty weedy test) */ 236799dd03e04a6914d90d5fee727d61d76905334becflorian if (sameIRExprs(env, e->Iex.ITE.iftrue, 236899dd03e04a6914d90d5fee727d61d76905334becflorian e->Iex.ITE.iffalse)) { 236999dd03e04a6914d90d5fee727d61d76905334becflorian e2 = e->Iex.ITE.iffalse; 23706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 2371708417d56d1798ffd62a05b7932da47cdc3d3337florian break; 2372708417d56d1798ffd62a05b7932da47cdc3d3337florian 2373708417d56d1798ffd62a05b7932da47cdc3d3337florian default: 2374708417d56d1798ffd62a05b7932da47cdc3d3337florian /* not considered */ 2375708417d56d1798ffd62a05b7932da47cdc3d3337florian break; 23760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2377d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 2378a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj /* Show cases where we've found but not folded 'op(t,t)'. Be 2379a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj careful not to call sameIRExprs with values of different types, 2380a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj though, else it will assert (and so it should!). We can't 2381a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj conveniently call typeOfIRExpr on the two args without a whole 2382a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj bunch of extra plumbing to pass in a type env, so just use a 2383a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj hacky test to check the arguments are not anything that might 2384a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj sameIRExprs to assert. This is only OK because this kludge is 2385a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj only used for debug printing, not for "real" operation. For 2386a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj "real" operation (ie, all other calls to sameIRExprs), it is 2387a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj essential that the to args have the same type. 2388a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj 2389a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj The "right" solution is to plumb the containing block's 2390a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj IRTypeEnv through to here and use typeOfIRExpr to be sure. But 2391a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj that's a bunch of extra parameter passing which will just slow 2392a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj down the normal case, for no purpose. */ 2393a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj if (vex_control.iropt_verbosity > 0 2394a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj && e == e2 2395a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj && e->tag == Iex_Binop 2396a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj && !debug_only_hack_sameIRExprs_might_assert(e->Iex.Binop.arg1, 2397a7e963847c4ceaf45d246a4a2e5982ea1f273ff4sewardj e->Iex.Binop.arg2) 2398cdb5feebd7e817c8207471ef734b43c51c14dee3florian && sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { 23994a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj vex_printf("vex iropt: fold_Expr: no ident rule for: "); 24004a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj ppIRExpr(e); 24014a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj vex_printf("\n"); 240264d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj } 240364d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj 240464d776c37f5dcb3475b0ca99aaafa448ba98b717sewardj /* Show the overall results of folding. */ 24050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT && e2 != e) { 24060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("FOLD: "); 24070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(e); vex_printf(" -> "); 24080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(e2); vex_printf("\n"); 24090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2410d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 24110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return e2; 2412f0e431671cb877601c2f2e551f42246469b4ee62sewardj 24130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj unhandled: 24140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# if 0 24150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n\n"); 24160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(e); 24170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("fold_Expr: no rule for the above"); 24180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# else 2419328b54be1d7eeb46108a2116b6d5643b5aa72627sewardj if (vex_control.iropt_verbosity > 0) { 24204a0bee01373f2ff1d0a915d30dd4f93bbd9729f9sewardj vex_printf("vex iropt: fold_Expr: no const rule for: "); 2421328b54be1d7eeb46108a2116b6d5643b5aa72627sewardj ppIRExpr(e); 2422328b54be1d7eeb46108a2116b6d5643b5aa72627sewardj vex_printf("\n"); 2423328b54be1d7eeb46108a2116b6d5643b5aa72627sewardj } 24240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return e2; 24250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# endif 24260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 2427f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2428044a215317abdd84dd7224a416595c43eedc96d3sewardj 24290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Apply the subst to a simple 1-level expression -- guaranteed to be 24300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 1-level due to previous flattening pass. */ 2431f0e431671cb877601c2f2e551f42246469b4ee62sewardj 24320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic IRExpr* subst_Expr ( IRExpr** env, IRExpr* ex ) 24330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 24340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (ex->tag) { 2435dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 2436dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (env[(Int)ex->Iex.RdTmp.tmp] != NULL) { 2437cdb5feebd7e817c8207471ef734b43c51c14dee3florian IRExpr *rhs = env[(Int)ex->Iex.RdTmp.tmp]; 2438cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (rhs->tag == Iex_RdTmp) 2439cdb5feebd7e817c8207471ef734b43c51c14dee3florian return rhs; 2440cdb5feebd7e817c8207471ef734b43c51c14dee3florian if (rhs->tag == Iex_Const 2441cdb5feebd7e817c8207471ef734b43c51c14dee3florian && rhs->Iex.Const.con->tag != Ico_F64i) 2442cdb5feebd7e817c8207471ef734b43c51c14dee3florian return rhs; 2443f0e431671cb877601c2f2e551f42246469b4ee62sewardj } 2444cdb5feebd7e817c8207471ef734b43c51c14dee3florian /* not bound in env */ 2445cdb5feebd7e817c8207471ef734b43c51c14dee3florian return ex; 244617442fe8094d0f82266e5a05509f62cac8f7539esewardj 24470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Const: 24480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 24490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return ex; 2450f0e431671cb877601c2f2e551f42246469b4ee62sewardj 24510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 2452496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(ex->Iex.GetI.ix)); 24530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_GetI( 24540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.GetI.descr, 24550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj subst_Expr(env, ex->Iex.GetI.ix), 24560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.GetI.bias 24570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2458cf1ea9c5ba5ae88b1f64345631b738959ab1c7f6sewardj 245996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian case Iex_Qop: { 246096d7cc3e7d54ad5af2af2821223b21f9a8516a59florian IRQop* qop = ex->Iex.Qop.details; 246196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian vassert(isIRAtom(qop->arg1)); 246296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian vassert(isIRAtom(qop->arg2)); 246396d7cc3e7d54ad5af2af2821223b21f9a8516a59florian vassert(isIRAtom(qop->arg3)); 246496d7cc3e7d54ad5af2af2821223b21f9a8516a59florian vassert(isIRAtom(qop->arg4)); 246540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return IRExpr_Qop( 246696d7cc3e7d54ad5af2af2821223b21f9a8516a59florian qop->op, 246796d7cc3e7d54ad5af2af2821223b21f9a8516a59florian subst_Expr(env, qop->arg1), 246896d7cc3e7d54ad5af2af2821223b21f9a8516a59florian subst_Expr(env, qop->arg2), 246996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian subst_Expr(env, qop->arg3), 247096d7cc3e7d54ad5af2af2821223b21f9a8516a59florian subst_Expr(env, qop->arg4) 247140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj ); 247296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian } 247340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj 2474420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian case Iex_Triop: { 2475420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian IRTriop* triop = ex->Iex.Triop.details; 2476420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian vassert(isIRAtom(triop->arg1)); 2477420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian vassert(isIRAtom(triop->arg2)); 2478420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian vassert(isIRAtom(triop->arg3)); 2479b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return IRExpr_Triop( 2480420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian triop->op, 2481420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian subst_Expr(env, triop->arg1), 2482420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian subst_Expr(env, triop->arg2), 2483420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian subst_Expr(env, triop->arg3) 2484b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj ); 2485420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian } 2486b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 24870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Binop: 2488496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(ex->Iex.Binop.arg1)); 2489496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(ex->Iex.Binop.arg2)); 24900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Binop( 24910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.Binop.op, 24920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj subst_Expr(env, ex->Iex.Binop.arg1), 24930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj subst_Expr(env, ex->Iex.Binop.arg2) 24940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2495044a215317abdd84dd7224a416595c43eedc96d3sewardj 24960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Unop: 2497496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(ex->Iex.Unop.arg)); 24980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Unop( 24990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.Unop.op, 25000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj subst_Expr(env, ex->Iex.Unop.arg) 25010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 25020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 2503af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 2504af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(ex->Iex.Load.addr)); 2505af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return IRExpr_Load( 2506af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj ex->Iex.Load.end, 2507af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj ex->Iex.Load.ty, 2508af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj subst_Expr(env, ex->Iex.Load.addr) 25090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 25100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 25110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_CCall: { 25120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 2513dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr** args2 = shallowCopyIRExprVec(ex->Iex.CCall.args); 25140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; args2[i]; i++) { 2515496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(args2[i])); 25160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj args2[i] = subst_Expr(env, args2[i]); 25178d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj } 25180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_CCall( 25190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.CCall.cee, 25200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ex->Iex.CCall.retty, 25210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj args2 25220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2523044a215317abdd84dd7224a416595c43eedc96d3sewardj } 25248d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj 252599dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 252699dd03e04a6914d90d5fee727d61d76905334becflorian vassert(isIRAtom(ex->Iex.ITE.cond)); 252799dd03e04a6914d90d5fee727d61d76905334becflorian vassert(isIRAtom(ex->Iex.ITE.iftrue)); 252899dd03e04a6914d90d5fee727d61d76905334becflorian vassert(isIRAtom(ex->Iex.ITE.iffalse)); 252999dd03e04a6914d90d5fee727d61d76905334becflorian return IRExpr_ITE( 253099dd03e04a6914d90d5fee727d61d76905334becflorian subst_Expr(env, ex->Iex.ITE.cond), 253199dd03e04a6914d90d5fee727d61d76905334becflorian subst_Expr(env, ex->Iex.ITE.iftrue), 253299dd03e04a6914d90d5fee727d61d76905334becflorian subst_Expr(env, ex->Iex.ITE.iffalse) 25330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 25340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 25350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 25360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n\n"); ppIRExpr(ex); 25370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("subst_Expr"); 25380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 25390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2540f0e431671cb877601c2f2e551f42246469b4ee62sewardj} 2541f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2542f0e431671cb877601c2f2e551f42246469b4ee62sewardj 25430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Apply the subst to stmt, then fold the result as much as possible. 2544d2445f60726580b450eca68ab40c568f9df338e2sewardj Much simplified due to stmt being previously flattened. As a 2545d2445f60726580b450eca68ab40c568f9df338e2sewardj result of this, the stmt may wind up being turned into a no-op. 2546d2445f60726580b450eca68ab40c568f9df338e2sewardj*/ 25470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic IRStmt* subst_and_fold_Stmt ( IRExpr** env, IRStmt* st ) 25480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 25490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# if 0 25500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\nsubst and fold stmt\n"); 25510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 25520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 25530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# endif 2554f0e431671cb877601c2f2e551f42246469b4ee62sewardj 25550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 25565a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 25575a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj vassert(isIRAtom(st->Ist.AbiHint.base)); 2558478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj vassert(isIRAtom(st->Ist.AbiHint.nia)); 25595a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj return IRStmt_AbiHint( 2560cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.AbiHint.base)), 2561478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj st->Ist.AbiHint.len, 2562cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.AbiHint.nia)) 25635a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj ); 25640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 2565496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Put.data)); 25660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRStmt_Put( 25670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st->Ist.Put.offset, 2568cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.Put.data)) 25690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2570f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2571d6f38b3f822f7d57adfc0da3410995d85d6a4597florian case Ist_PutI: { 2572d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *puti, *puti2; 2573d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti = st->Ist.PutI.details; 2574d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(puti->ix)); 2575d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(puti->data)); 2576d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti2 = mkIRPutI(puti->descr, 2577d6f38b3f822f7d57adfc0da3410995d85d6a4597florian fold_Expr(env, subst_Expr(env, puti->ix)), 2578d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->bias, 2579d6f38b3f822f7d57adfc0da3410995d85d6a4597florian fold_Expr(env, subst_Expr(env, puti->data))); 2580d6f38b3f822f7d57adfc0da3410995d85d6a4597florian return IRStmt_PutI(puti2); 2581d6f38b3f822f7d57adfc0da3410995d85d6a4597florian } 2582f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2583dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 2584dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj /* This is the one place where an expr (st->Ist.WrTmp.data) is 25850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj allowed to be more than just a constant or a tmp. */ 2586dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRStmt_WrTmp( 2587dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj st->Ist.WrTmp.tmp, 2588cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.WrTmp.data)) 25890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2590f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2591af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 2592af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.addr)); 2593af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.data)); 2594af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return IRStmt_Store( 2595af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj st->Ist.Store.end, 2596cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.Store.addr)), 2597cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.Store.data)) 25980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 2599f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2600cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 2601cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 2602cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->addr)); 2603cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->data)); 2604cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->guard)); 2605cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* faddr = fold_Expr(env, subst_Expr(env, sg->addr)); 2606cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* fdata = fold_Expr(env, subst_Expr(env, sg->data)); 2607cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* fguard = fold_Expr(env, subst_Expr(env, sg->guard)); 2608cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (fguard->tag == Iex_Const) { 2609cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* The condition on this store has folded down to a constant. */ 2610cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(fguard->Iex.Const.con->tag == Ico_U1); 2611cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (fguard->Iex.Const.con->Ico.U1 == False) { 2612cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_NoOp(); 2613cfe046e178666280b87da998b1b52ecda03ecd89sewardj } else { 2614cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(fguard->Iex.Const.con->Ico.U1 == True); 2615cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_Store(sg->end, faddr, fdata); 2616cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2617cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2618cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_StoreG(sg->end, faddr, fdata, fguard); 2619cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2620cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2621cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 2622cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* This is complicated. If the guard folds down to 'false', 2623cfe046e178666280b87da998b1b52ecda03ecd89sewardj we can replace it with an assignment 'dst := alt', but if 2624cfe046e178666280b87da998b1b52ecda03ecd89sewardj the guard folds down to 'true', we can't conveniently 2625cfe046e178666280b87da998b1b52ecda03ecd89sewardj replace it with an unconditional load, because doing so 2626cfe046e178666280b87da998b1b52ecda03ecd89sewardj requires generating a new temporary, and that is not easy 2627cfe046e178666280b87da998b1b52ecda03ecd89sewardj to do at this point. */ 2628cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 2629cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->addr)); 2630cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->alt)); 2631cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->guard)); 2632cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* faddr = fold_Expr(env, subst_Expr(env, lg->addr)); 2633cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* falt = fold_Expr(env, subst_Expr(env, lg->alt)); 2634cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* fguard = fold_Expr(env, subst_Expr(env, lg->guard)); 2635cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (fguard->tag == Iex_Const) { 2636cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* The condition on this load has folded down to a constant. */ 2637cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(fguard->Iex.Const.con->tag == Ico_U1); 2638cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (fguard->Iex.Const.con->Ico.U1 == False) { 2639cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* The load is not going to happen -- instead 'alt' is 2640cfe046e178666280b87da998b1b52ecda03ecd89sewardj assigned to 'dst'. */ 2641cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_WrTmp(lg->dst, falt); 2642cfe046e178666280b87da998b1b52ecda03ecd89sewardj } else { 2643cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(fguard->Iex.Const.con->Ico.U1 == True); 2644cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* The load is always going to happen. We want to 2645cfe046e178666280b87da998b1b52ecda03ecd89sewardj convert to an unconditional load and assign to 'dst' 2646cfe046e178666280b87da998b1b52ecda03ecd89sewardj (IRStmt_WrTmp). Problem is we need an extra temp to 2647cfe046e178666280b87da998b1b52ecda03ecd89sewardj hold the loaded value, but none is available. 2648cfe046e178666280b87da998b1b52ecda03ecd89sewardj Instead, reconstitute the conditional load (with 2649cfe046e178666280b87da998b1b52ecda03ecd89sewardj folded args, of course) and let the caller of this 2650cfe046e178666280b87da998b1b52ecda03ecd89sewardj routine deal with the problem. */ 2651cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2652cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2653cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_LoadG(lg->end, lg->cvt, lg->dst, faddr, falt, fguard); 2654cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2655cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2656e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: { 2657e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRCAS *cas, *cas2; 2658e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 2659e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->addr)); 2660e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(cas->expdHi == NULL || isIRAtom(cas->expdHi)); 2661e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->expdLo)); 2662e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(cas->dataHi == NULL || isIRAtom(cas->dataHi)); 2663e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->dataLo)); 2664e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas2 = mkIRCAS( 2665e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas->oldHi, cas->oldLo, cas->end, 2666cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, cas->addr)), 26676399f81e98cd8c7fbd55255c67f051a0a1873658sewardj cas->expdHi ? fold_Expr(env, subst_Expr(env, cas->expdHi)) 26686399f81e98cd8c7fbd55255c67f051a0a1873658sewardj : NULL, 2669cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, cas->expdLo)), 26706399f81e98cd8c7fbd55255c67f051a0a1873658sewardj cas->dataHi ? fold_Expr(env, subst_Expr(env, cas->dataHi)) 26716399f81e98cd8c7fbd55255c67f051a0a1873658sewardj : NULL, 2672cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, cas->dataLo)) 2673e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj ); 2674e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return IRStmt_CAS(cas2); 2675e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj } 2676e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 2677e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 2678e768e92e054cde495849a5c842a477d287677f78sewardj vassert(isIRAtom(st->Ist.LLSC.addr)); 2679e768e92e054cde495849a5c842a477d287677f78sewardj if (st->Ist.LLSC.storedata) 2680e768e92e054cde495849a5c842a477d287677f78sewardj vassert(isIRAtom(st->Ist.LLSC.storedata)); 2681e768e92e054cde495849a5c842a477d287677f78sewardj return IRStmt_LLSC( 2682e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.end, 2683e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.result, 2684cdb5feebd7e817c8207471ef734b43c51c14dee3florian fold_Expr(env, subst_Expr(env, st->Ist.LLSC.addr)), 2685e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.storedata 2686cdb5feebd7e817c8207471ef734b43c51c14dee3florian ? fold_Expr(env, subst_Expr(env, st->Ist.LLSC.storedata)) 2687e768e92e054cde495849a5c842a477d287677f78sewardj : NULL 2688e768e92e054cde495849a5c842a477d287677f78sewardj ); 2689e768e92e054cde495849a5c842a477d287677f78sewardj 26900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: { 26910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 26920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRDirty *d, *d2; 26930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d = st->Ist.Dirty.details; 26940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d2 = emptyIRDirty(); 26950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *d2 = *d; 2696dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj d2->args = shallowCopyIRExprVec(d2->args); 26970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d2->mFx != Ifx_None) { 2698496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(d2->mAddr)); 2699cdb5feebd7e817c8207471ef734b43c51c14dee3florian d2->mAddr = fold_Expr(env, subst_Expr(env, d2->mAddr)); 27000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2701496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(d2->guard)); 2702cdb5feebd7e817c8207471ef734b43c51c14dee3florian d2->guard = fold_Expr(env, subst_Expr(env, d2->guard)); 27030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; d2->args[i]; i++) { 270474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d2->args[i]; 2705ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) { 270674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj vassert(isIRAtom(arg)); 270774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj d2->args[i] = fold_Expr(env, subst_Expr(env, arg)); 270874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 27090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 27100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRStmt_Dirty(d2); 2711f0e431671cb877601c2f2e551f42246469b4ee62sewardj } 2712f0e431671cb877601c2f2e551f42246469b4ee62sewardj 2713f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 27142f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj return IRStmt_IMark(st->Ist.IMark.addr, 27152f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj st->Ist.IMark.len, 27162f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj st->Ist.IMark.delta); 2717f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj 2718d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 2719d2445f60726580b450eca68ab40c568f9df338e2sewardj return IRStmt_NoOp(); 2720d2445f60726580b450eca68ab40c568f9df338e2sewardj 2721c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 2722c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj return IRStmt_MBE(st->Ist.MBE.event); 27233e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj 27240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Exit: { 27250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* fcond; 2726496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Exit.guard)); 2727cdb5feebd7e817c8207471ef734b43c51c14dee3florian fcond = fold_Expr(env, subst_Expr(env, st->Ist.Exit.guard)); 27280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (fcond->tag == Iex_Const) { 27290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Interesting. The condition on this exit has folded down to 27300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj a constant. */ 27310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(fcond->Iex.Const.con->tag == Ico_U1); 27320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (fcond->Iex.Const.con->Ico.U1 == False) { 27330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* exit is never going to happen, so dump the statement. */ 2734d2445f60726580b450eca68ab40c568f9df338e2sewardj return IRStmt_NoOp(); 27350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 27360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(fcond->Iex.Const.con->Ico.U1 == True); 2737e810c1940eab1792cfd312635708c540b9a9bfdfsewardj /* Hmmm. The exit has become unconditional. Leave it 2738e810c1940eab1792cfd312635708c540b9a9bfdfsewardj as it is for now, since we'd have to truncate the BB 2739e810c1940eab1792cfd312635708c540b9a9bfdfsewardj at this point, which is tricky. Such truncation is 2740e810c1940eab1792cfd312635708c540b9a9bfdfsewardj done later by the dead-code elimination pass. */ 27410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* fall out into the reconstruct-the-exit code. */ 27420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_verbosity > 0) 27430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* really a misuse of vex_control.iropt_verbosity */ 27440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("vex iropt: IRStmt_Exit became unconditional\n"); 27452963239357452b96dbe6de1b3f8b626ea3305780sewardj } 2746f0e431671cb877601c2f2e551f42246469b4ee62sewardj } 2747c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj return IRStmt_Exit(fcond, st->Ist.Exit.jk, 2748c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj st->Ist.Exit.dst, st->Ist.Exit.offsIP); 2749f0e431671cb877601c2f2e551f42246469b4ee62sewardj } 2750f0e431671cb877601c2f2e551f42246469b4ee62sewardj 27510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 27520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRStmt(st); 27530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("subst_and_fold_Stmt"); 27540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 27550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 27560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 27570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 2758dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjIRSB* cprop_BB ( IRSB* in ) 27590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 27600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 2761dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB* out; 27620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st2; 27630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int n_tmps = in->tyenv->types_used; 2764d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian IRExpr** env = LibVEX_Alloc_inline(n_tmps * sizeof(IRExpr*)); 2765cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Keep track of IRStmt_LoadGs that we need to revisit after 2766cfe046e178666280b87da998b1b52ecda03ecd89sewardj processing all the other statements. */ 2767cfe046e178666280b87da998b1b52ecda03ecd89sewardj const Int N_FIXUPS = 16; 2768cfe046e178666280b87da998b1b52ecda03ecd89sewardj Int fixups[N_FIXUPS]; /* indices in the stmt array of 'out' */ 2769cfe046e178666280b87da998b1b52ecda03ecd89sewardj Int n_fixups = 0; 27700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 2771dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj out = emptyIRSB(); 2772dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj out->tyenv = deepCopyIRTypeEnv( in->tyenv ); 27730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 27740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Set up the env with which travels forward. This holds a 2775cdb5feebd7e817c8207471ef734b43c51c14dee3florian substitution, mapping IRTemps to IRExprs. The environment 2776cdb5feebd7e817c8207471ef734b43c51c14dee3florian is to be applied as we move along. Keys are IRTemps. 2777cdb5feebd7e817c8207471ef734b43c51c14dee3florian Values are IRExpr*s. 27780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 27790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < n_tmps; i++) 27800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj env[i] = NULL; 2781f0e431671cb877601c2f2e551f42246469b4ee62sewardj 27820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* For each original SSA-form stmt ... */ 27830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < in->stmts_used; i++) { 2784f0e431671cb877601c2f2e551f42246469b4ee62sewardj 27850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* First apply the substitution to the current stmt. This 27860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj propagates in any constants and tmp-tmp assignments 27870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj accumulated prior to this point. As part of the subst_Stmt 27880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj call, also then fold any constant expressions resulting. */ 278984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 27900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st2 = in->stmts[i]; 279184ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 27920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* perhaps st2 is already a no-op? */ 27938bee6d15808653a71717c256a3abe96993439d25sewardj if (st2->tag == Ist_NoOp) continue; 279484ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 27950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st2 = subst_and_fold_Stmt( env, st2 ); 279684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 2797cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Deal with some post-folding special cases. */ 2798cfe046e178666280b87da998b1b52ecda03ecd89sewardj switch (st2->tag) { 2799cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2800cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* If the statement has been folded into a no-op, forget 2801cfe046e178666280b87da998b1b52ecda03ecd89sewardj it. */ 2802cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_NoOp: 2803cfe046e178666280b87da998b1b52ecda03ecd89sewardj continue; 2804cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2805cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* If the statement assigns to an IRTemp add it to the 2806cfe046e178666280b87da998b1b52ecda03ecd89sewardj running environment. This is for the benefit of copy 2807cfe046e178666280b87da998b1b52ecda03ecd89sewardj propagation and to allow sameIRExpr look through 2808cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRTemps. */ 2809cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_WrTmp: { 2810cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(env[(Int)(st2->Ist.WrTmp.tmp)] == NULL); 2811cfe046e178666280b87da998b1b52ecda03ecd89sewardj env[(Int)(st2->Ist.WrTmp.tmp)] = st2->Ist.WrTmp.data; 2812cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2813cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* 't1 = t2' -- don't add to BB; will be optimized out */ 2814cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (st2->Ist.WrTmp.data->tag == Iex_RdTmp) 2815cfe046e178666280b87da998b1b52ecda03ecd89sewardj continue; 2816cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2817cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* 't = const' && 'const != F64i' -- don't add to BB 2818cfe046e178666280b87da998b1b52ecda03ecd89sewardj Note, we choose not to propagate const when const is an 2819cfe046e178666280b87da998b1b52ecda03ecd89sewardj F64i, so that F64i literals can be CSE'd later. This 2820cfe046e178666280b87da998b1b52ecda03ecd89sewardj helps x86 floating point code generation. */ 2821cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (st2->Ist.WrTmp.data->tag == Iex_Const 2822cfe046e178666280b87da998b1b52ecda03ecd89sewardj && st2->Ist.WrTmp.data->Iex.Const.con->tag != Ico_F64i) { 2823cfe046e178666280b87da998b1b52ecda03ecd89sewardj continue; 2824cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2825cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* else add it to the output, as normal */ 2826cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 2827cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 282884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 2829cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 2830cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st2->Ist.LoadG.details; 2831cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* guard = lg->guard; 2832cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (guard->tag == Iex_Const) { 2833cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* The guard has folded to a constant, and that 2834cfe046e178666280b87da998b1b52ecda03ecd89sewardj constant must be 1:I1, since subst_and_fold_Stmt 2835cfe046e178666280b87da998b1b52ecda03ecd89sewardj folds out the case 0:I1 by itself. */ 2836cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(guard->Iex.Const.con->tag == Ico_U1); 2837cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(guard->Iex.Const.con->Ico.U1 == True); 2838cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Add a NoOp here as a placeholder, and make a note of 2839cfe046e178666280b87da998b1b52ecda03ecd89sewardj where it is in the output block. Afterwards we'll 2840cfe046e178666280b87da998b1b52ecda03ecd89sewardj come back here and transform the NoOp and the LoadG 2841cfe046e178666280b87da998b1b52ecda03ecd89sewardj into a load-convert pair. The fixups[] entry 2842cfe046e178666280b87da998b1b52ecda03ecd89sewardj refers to the inserted NoOp, and we expect to find 2843cfe046e178666280b87da998b1b52ecda03ecd89sewardj the relevant LoadG immediately after it. */ 2844cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(n_fixups >= 0 && n_fixups <= N_FIXUPS); 2845cfe046e178666280b87da998b1b52ecda03ecd89sewardj if (n_fixups < N_FIXUPS) { 2846cfe046e178666280b87da998b1b52ecda03ecd89sewardj fixups[n_fixups++] = out->stmts_used; 2847cfe046e178666280b87da998b1b52ecda03ecd89sewardj addStmtToIRSB( out, IRStmt_NoOp() ); 2848cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2849cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2850cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* And always add the LoadG to the output, regardless. */ 2851cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 2852cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2853cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2854cfe046e178666280b87da998b1b52ecda03ecd89sewardj default: 2855cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 28560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 2857cdb5feebd7e817c8207471ef734b43c51c14dee3florian 2858cdb5feebd7e817c8207471ef734b43c51c14dee3florian /* Not interesting, copy st2 into the output block. */ 2859cdb5feebd7e817c8207471ef734b43c51c14dee3florian addStmtToIRSB( out, st2 ); 286084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 28610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 2862cfe046e178666280b87da998b1b52ecda03ecd89sewardj# if STATS_IROPT 2863cdb5feebd7e817c8207471ef734b43c51c14dee3florian vex_printf("sameIRExpr: invoked = %u/%u equal = %u/%u max_nodes = %u\n", 2864cdb5feebd7e817c8207471ef734b43c51c14dee3florian invocation_count, recursion_count, success_count, 2865cdb5feebd7e817c8207471ef734b43c51c14dee3florian recursion_success_count, max_nodes_visited); 2866cfe046e178666280b87da998b1b52ecda03ecd89sewardj# endif 2867cdb5feebd7e817c8207471ef734b43c51c14dee3florian 28680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj out->next = subst_Expr( env, in->next ); 28690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj out->jumpkind = in->jumpkind; 2870c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj out->offsIP = in->offsIP; 2871cfe046e178666280b87da998b1b52ecda03ecd89sewardj 2872cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Process any leftover unconditional LoadGs that we noticed 2873cfe046e178666280b87da998b1b52ecda03ecd89sewardj in the main pass. */ 2874cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(n_fixups >= 0 && n_fixups <= N_FIXUPS); 2875cfe046e178666280b87da998b1b52ecda03ecd89sewardj for (i = 0; i < n_fixups; i++) { 2876cfe046e178666280b87da998b1b52ecda03ecd89sewardj Int ix = fixups[i]; 2877cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Carefully verify that the LoadG has the expected form. */ 2878cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(ix >= 0 && ix+1 < out->stmts_used); 2879cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStmt* nop = out->stmts[ix]; 2880cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStmt* lgu = out->stmts[ix+1]; 2881cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(nop->tag == Ist_NoOp); 2882cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(lgu->tag == Ist_LoadG); 2883cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = lgu->Ist.LoadG.details; 2884cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr* guard = lg->guard; 2885cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(guard->Iex.Const.con->tag == Ico_U1); 2886cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(guard->Iex.Const.con->Ico.U1 == True); 2887cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Figure out the load and result types, and the implied 2888cfe046e178666280b87da998b1b52ecda03ecd89sewardj conversion operation. */ 2889cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRType cvtRes = Ity_INVALID, cvtArg = Ity_INVALID; 2890cfe046e178666280b87da998b1b52ecda03ecd89sewardj typeOfIRLoadGOp(lg->cvt, &cvtRes, &cvtArg); 2891cfe046e178666280b87da998b1b52ecda03ecd89sewardj IROp cvtOp = Iop_INVALID; 2892cfe046e178666280b87da998b1b52ecda03ecd89sewardj switch (lg->cvt) { 289370dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case ILGop_IdentV128: 289470dbeb0232ebafbf0977549b1c72ff53c8ef9863sewardj case ILGop_Ident64: 2895cfe046e178666280b87da998b1b52ecda03ecd89sewardj case ILGop_Ident32: break; 2896cfe046e178666280b87da998b1b52ecda03ecd89sewardj case ILGop_8Uto32: cvtOp = Iop_8Uto32; break; 2897cfe046e178666280b87da998b1b52ecda03ecd89sewardj case ILGop_8Sto32: cvtOp = Iop_8Sto32; break; 2898cfe046e178666280b87da998b1b52ecda03ecd89sewardj case ILGop_16Uto32: cvtOp = Iop_16Uto32; break; 2899cfe046e178666280b87da998b1b52ecda03ecd89sewardj case ILGop_16Sto32: cvtOp = Iop_16Sto32; break; 2900cfe046e178666280b87da998b1b52ecda03ecd89sewardj default: vpanic("cprop_BB: unhandled ILGOp"); 2901cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2902cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Replace the placeholder NoOp by the required unconditional 2903cfe046e178666280b87da998b1b52ecda03ecd89sewardj load. */ 2904cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRTemp tLoaded = newIRTemp(out->tyenv, cvtArg); 2905cfe046e178666280b87da998b1b52ecda03ecd89sewardj out->stmts[ix] 2906cfe046e178666280b87da998b1b52ecda03ecd89sewardj = IRStmt_WrTmp(tLoaded, 2907cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRExpr_Load(lg->end, cvtArg, lg->addr)); 2908cfe046e178666280b87da998b1b52ecda03ecd89sewardj /* Replace the LoadG by a conversion from the loaded value's 2909cfe046e178666280b87da998b1b52ecda03ecd89sewardj type to the required result type. */ 2910cfe046e178666280b87da998b1b52ecda03ecd89sewardj out->stmts[ix+1] 2911cfe046e178666280b87da998b1b52ecda03ecd89sewardj = IRStmt_WrTmp( 2912cfe046e178666280b87da998b1b52ecda03ecd89sewardj lg->dst, cvtOp == Iop_INVALID 2913cfe046e178666280b87da998b1b52ecda03ecd89sewardj ? IRExpr_RdTmp(tLoaded) 2914cfe046e178666280b87da998b1b52ecda03ecd89sewardj : IRExpr_Unop(cvtOp, IRExpr_RdTmp(tLoaded))); 2915cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 2916cfe046e178666280b87da998b1b52ecda03ecd89sewardj 29170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return out; 291884ff0657940e62f38e618ea18bac6f27ce0e741fsewardj} 291984ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 29202963239357452b96dbe6de1b3f8b626ea3305780sewardj 29212963239357452b96dbe6de1b3f8b626ea3305780sewardj/*---------------------------------------------------------------*/ 29220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Dead code (t = E) removal ---*/ 29232963239357452b96dbe6de1b3f8b626ea3305780sewardj/*---------------------------------------------------------------*/ 29242963239357452b96dbe6de1b3f8b626ea3305780sewardj 2925e810c1940eab1792cfd312635708c540b9a9bfdfsewardj/* As a side effect, also removes all code following an unconditional 2926e810c1940eab1792cfd312635708c540b9a9bfdfsewardj side exit. */ 2927e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 29280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* The type of the HashHW map is: a map from IRTemp to nothing 29290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj -- really just operating a set or IRTemps. 29302963239357452b96dbe6de1b3f8b626ea3305780sewardj*/ 29310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 29320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjinline 29330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void addUses_Temp ( Bool* set, IRTemp tmp ) 29342963239357452b96dbe6de1b3f8b626ea3305780sewardj{ 29350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj set[(Int)tmp] = True; 293617442fe8094d0f82266e5a05509f62cac8f7539esewardj} 293717442fe8094d0f82266e5a05509f62cac8f7539esewardj 29380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void addUses_Expr ( Bool* set, IRExpr* e ) 293917442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 294017442fe8094d0f82266e5a05509f62cac8f7539esewardj Int i; 29412963239357452b96dbe6de1b3f8b626ea3305780sewardj switch (e->tag) { 29420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 29430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, e->Iex.GetI.ix); 29442963239357452b96dbe6de1b3f8b626ea3305780sewardj return; 294599dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 294699dd03e04a6914d90d5fee727d61d76905334becflorian addUses_Expr(set, e->Iex.ITE.cond); 294799dd03e04a6914d90d5fee727d61d76905334becflorian addUses_Expr(set, e->Iex.ITE.iftrue); 294899dd03e04a6914d90d5fee727d61d76905334becflorian addUses_Expr(set, e->Iex.ITE.iffalse); 29490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 29500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_CCall: 29510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; e->Iex.CCall.args[i]; i++) 29520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, e->Iex.CCall.args[i]); 29530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 2954af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 2955af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj addUses_Expr(set, e->Iex.Load.addr); 29560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 295740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj case Iex_Qop: 295896d7cc3e7d54ad5af2af2821223b21f9a8516a59florian addUses_Expr(set, e->Iex.Qop.details->arg1); 295996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian addUses_Expr(set, e->Iex.Qop.details->arg2); 296096d7cc3e7d54ad5af2af2821223b21f9a8516a59florian addUses_Expr(set, e->Iex.Qop.details->arg3); 296196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian addUses_Expr(set, e->Iex.Qop.details->arg4); 296240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return; 2963b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Iex_Triop: 2964420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian addUses_Expr(set, e->Iex.Triop.details->arg1); 2965420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian addUses_Expr(set, e->Iex.Triop.details->arg2); 2966420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian addUses_Expr(set, e->Iex.Triop.details->arg3); 2967b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return; 29680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Binop: 29690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, e->Iex.Binop.arg1); 29700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, e->Iex.Binop.arg2); 29710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 29720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Unop: 29730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, e->Iex.Unop.arg); 29740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 2975dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 2976dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addUses_Temp(set, e->Iex.RdTmp.tmp); 29770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 29780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Const: 29790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 29800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 29810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 29820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 29830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(e); 29840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("addUses_Expr"); 29850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 29860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 29870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 29880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void addUses_Stmt ( Bool* set, IRStmt* st ) 29890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 29900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 29910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRDirty* d; 2992e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRCAS* cas; 29930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 29945a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 29955a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj addUses_Expr(set, st->Ist.AbiHint.base); 2996478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj addUses_Expr(set, st->Ist.AbiHint.nia); 29975a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj return; 29980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_PutI: 2999d6f38b3f822f7d57adfc0da3410995d85d6a4597florian addUses_Expr(set, st->Ist.PutI.details->ix); 3000d6f38b3f822f7d57adfc0da3410995d85d6a4597florian addUses_Expr(set, st->Ist.PutI.details->data); 30010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 3002dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 3003dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addUses_Expr(set, st->Ist.WrTmp.data); 30040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 30050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 30060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, st->Ist.Put.data); 30070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 3008af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 3009af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj addUses_Expr(set, st->Ist.Store.addr); 3010af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj addUses_Expr(set, st->Ist.Store.data); 30110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 3012cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 3013cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 3014cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, sg->addr); 3015cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, sg->data); 3016cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, sg->guard); 3017cfe046e178666280b87da998b1b52ecda03ecd89sewardj return; 3018cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 3019cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 3020cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 3021cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, lg->addr); 3022cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, lg->alt); 3023cfe046e178666280b87da998b1b52ecda03ecd89sewardj addUses_Expr(set, lg->guard); 3024cfe046e178666280b87da998b1b52ecda03ecd89sewardj return; 3025cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 3026e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 3027e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 3028e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addUses_Expr(set, cas->addr); 3029e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (cas->expdHi) 3030e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addUses_Expr(set, cas->expdHi); 3031e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addUses_Expr(set, cas->expdLo); 3032e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (cas->dataHi) 3033e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addUses_Expr(set, cas->dataHi); 3034e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj addUses_Expr(set, cas->dataLo); 3035e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 3036e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 3037e768e92e054cde495849a5c842a477d287677f78sewardj addUses_Expr(set, st->Ist.LLSC.addr); 3038e768e92e054cde495849a5c842a477d287677f78sewardj if (st->Ist.LLSC.storedata) 3039e768e92e054cde495849a5c842a477d287677f78sewardj addUses_Expr(set, st->Ist.LLSC.storedata); 3040e768e92e054cde495849a5c842a477d287677f78sewardj return; 30410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: 30420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d = st->Ist.Dirty.details; 30430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d->mFx != Ifx_None) 30440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, d->mAddr); 30450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, d->guard); 304674142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (i = 0; d->args[i] != NULL; i++) { 304774142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d->args[i]; 3048ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 304974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj addUses_Expr(set, arg); 305074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 30510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 3052d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 3053f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 3054c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 30553e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj return; 30560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Exit: 30570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, st->Ist.Exit.guard); 30582963239357452b96dbe6de1b3f8b626ea3305780sewardj return; 30590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 30600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 30610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 30620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("addUses_Stmt"); 30630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 30640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 30650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 30660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 30670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Is this literally IRExpr_Const(IRConst_U1(False)) ? */ 30680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic Bool isZeroU1 ( IRExpr* e ) 30690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 30709d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( e->tag == Iex_Const 30719d2e769a9368d2b22c32a4764a70e9da38769628sewardj && e->Iex.Const.con->tag == Ico_U1 30729d2e769a9368d2b22c32a4764a70e9da38769628sewardj && e->Iex.Const.con->Ico.U1 == False ); 30730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 30740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3075e810c1940eab1792cfd312635708c540b9a9bfdfsewardj/* Is this literally IRExpr_Const(IRConst_U1(True)) ? */ 3076e810c1940eab1792cfd312635708c540b9a9bfdfsewardjstatic Bool isOneU1 ( IRExpr* e ) 3077e810c1940eab1792cfd312635708c540b9a9bfdfsewardj{ 3078e810c1940eab1792cfd312635708c540b9a9bfdfsewardj return toBool( e->tag == Iex_Const 3079e810c1940eab1792cfd312635708c540b9a9bfdfsewardj && e->Iex.Const.con->tag == Ico_U1 3080e810c1940eab1792cfd312635708c540b9a9bfdfsewardj && e->Iex.Const.con->Ico.U1 == True ); 3081e810c1940eab1792cfd312635708c540b9a9bfdfsewardj} 3082e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 30830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3084dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* Note, this destructively modifies the given IRSB. */ 30850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 30860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Scan backwards through statements, carrying a set of IRTemps which 30870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj are known to be used after the current point. On encountering 't = 30880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj E', delete the binding if it is not used. Otherwise, add any temp 3089e810c1940eab1792cfd312635708c540b9a9bfdfsewardj uses to the set and keep on moving backwards. 3090e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 3091e810c1940eab1792cfd312635708c540b9a9bfdfsewardj As an enhancement, the first (backwards) pass searches for IR exits 3092e810c1940eab1792cfd312635708c540b9a9bfdfsewardj with always-taken conditions and notes the location of the earliest 3093e810c1940eab1792cfd312635708c540b9a9bfdfsewardj one in the block. If any such are found, a second pass copies the 3094e810c1940eab1792cfd312635708c540b9a9bfdfsewardj exit destination and jump kind to the bb-end. Then, the exit and 3095e810c1940eab1792cfd312635708c540b9a9bfdfsewardj all statements following it are turned into no-ops. 3096e810c1940eab1792cfd312635708c540b9a9bfdfsewardj*/ 30970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3098dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj/* notstatic */ void do_deadcode_BB ( IRSB* bb ) 30990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 3100e810c1940eab1792cfd312635708c540b9a9bfdfsewardj Int i, i_unconditional_exit; 31010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int n_tmps = bb->tyenv->types_used; 3102d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian Bool* set = LibVEX_Alloc_inline(n_tmps * sizeof(Bool)); 31030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 31040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 31050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < n_tmps; i++) 31060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj set[i] = False; 31070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 31080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* start off by recording IRTemp uses in the next field. */ 31090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Expr(set, bb->next); 31100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3111e810c1940eab1792cfd312635708c540b9a9bfdfsewardj /* First pass */ 3112e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 31130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Work backwards through the stmts */ 3114e810c1940eab1792cfd312635708c540b9a9bfdfsewardj i_unconditional_exit = -1; 31150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb->stmts_used-1; i >= 0; i--) { 31160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 31178bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 31180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 3119e810c1940eab1792cfd312635708c540b9a9bfdfsewardj /* take note of any unconditional exits */ 3120e810c1940eab1792cfd312635708c540b9a9bfdfsewardj if (st->tag == Ist_Exit 3121e810c1940eab1792cfd312635708c540b9a9bfdfsewardj && isOneU1(st->Ist.Exit.guard)) 3122e810c1940eab1792cfd312635708c540b9a9bfdfsewardj i_unconditional_exit = i; 3123dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp 3124dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && set[(Int)(st->Ist.WrTmp.tmp)] == False) { 31250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* it's an IRTemp which never got used. Delete it. */ 31260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 31270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("DEAD: "); 31280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 31290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 31300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 3131d2445f60726580b450eca68ab40c568f9df338e2sewardj bb->stmts[i] = IRStmt_NoOp(); 31320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 31330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 31340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Dirty 31350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && st->Ist.Dirty.details->guard 31360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && isZeroU1(st->Ist.Dirty.details->guard)) { 3137d2445f60726580b450eca68ab40c568f9df338e2sewardj /* This is a dirty helper which will never get called. 3138d2445f60726580b450eca68ab40c568f9df338e2sewardj Delete it. */ 3139d2445f60726580b450eca68ab40c568f9df338e2sewardj bb->stmts[i] = IRStmt_NoOp(); 31400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 31410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else { 31420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Note any IRTemp uses made by the current statement. */ 31430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addUses_Stmt(set, st); 31440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 31450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 3146e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 3147e810c1940eab1792cfd312635708c540b9a9bfdfsewardj /* Optional second pass: if any unconditional exits were found, 3148e810c1940eab1792cfd312635708c540b9a9bfdfsewardj delete them and all following statements. */ 3149e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 3150e810c1940eab1792cfd312635708c540b9a9bfdfsewardj if (i_unconditional_exit != -1) { 3151e810c1940eab1792cfd312635708c540b9a9bfdfsewardj if (0) vex_printf("ZAPPING ALL FORWARDS from %d\n", 3152e810c1940eab1792cfd312635708c540b9a9bfdfsewardj i_unconditional_exit); 3153e810c1940eab1792cfd312635708c540b9a9bfdfsewardj vassert(i_unconditional_exit >= 0 3154e810c1940eab1792cfd312635708c540b9a9bfdfsewardj && i_unconditional_exit < bb->stmts_used); 3155e810c1940eab1792cfd312635708c540b9a9bfdfsewardj bb->next 3156e810c1940eab1792cfd312635708c540b9a9bfdfsewardj = IRExpr_Const( bb->stmts[i_unconditional_exit]->Ist.Exit.dst ); 3157e810c1940eab1792cfd312635708c540b9a9bfdfsewardj bb->jumpkind 3158e810c1940eab1792cfd312635708c540b9a9bfdfsewardj = bb->stmts[i_unconditional_exit]->Ist.Exit.jk; 3159c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj bb->offsIP 3160c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj = bb->stmts[i_unconditional_exit]->Ist.Exit.offsIP; 3161e810c1940eab1792cfd312635708c540b9a9bfdfsewardj for (i = i_unconditional_exit; i < bb->stmts_used; i++) 3162e810c1940eab1792cfd312635708c540b9a9bfdfsewardj bb->stmts[i] = IRStmt_NoOp(); 3163e810c1940eab1792cfd312635708c540b9a9bfdfsewardj } 31640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 31652963239357452b96dbe6de1b3f8b626ea3305780sewardj 3166e810c1940eab1792cfd312635708c540b9a9bfdfsewardj 31670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 31680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Specialisation of helper function calls, in ---*/ 31690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- collaboration with the front end ---*/ 31700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 31712963239357452b96dbe6de1b3f8b626ea3305780sewardj 31720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic 3173be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardjIRSB* spec_helpers_BB( 3174be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRSB* bb, 31751ff4756e1731485e6bf3cd96717cd8398daec1f2florian IRExpr* (*specHelper) (const HChar*, IRExpr**, IRStmt**, Int) 3176be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj ) 31770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 3178b92307503d4fb9265136e182d10c42ebb9dd8272sewardj Int i; 31790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 31800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* ex; 3181b92307503d4fb9265136e182d10c42ebb9dd8272sewardj Bool any = False; 31822963239357452b96dbe6de1b3f8b626ea3305780sewardj 31830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb->stmts_used-1; i >= 0; i--) { 31840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 31852963239357452b96dbe6de1b3f8b626ea3305780sewardj 3186dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag != Ist_WrTmp 3187dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj || st->Ist.WrTmp.data->tag != Iex_CCall) 31888bee6d15808653a71717c256a3abe96993439d25sewardj continue; 31892963239357452b96dbe6de1b3f8b626ea3305780sewardj 3190dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ex = (*specHelper)( st->Ist.WrTmp.data->Iex.CCall.cee->name, 3191be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj st->Ist.WrTmp.data->Iex.CCall.args, 3192be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj &bb->stmts[0], i ); 31930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (!ex) 31940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* the front end can't think of a suitable replacement */ 31950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 3196f6501996bf1f0e2a8ce6817efe9edf6b619bc85bsewardj 31970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* We got something better. Install it in the bb. */ 3198b92307503d4fb9265136e182d10c42ebb9dd8272sewardj any = True; 31990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts[i] 3200dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj = IRStmt_WrTmp(st->Ist.WrTmp.tmp, ex); 32012963239357452b96dbe6de1b3f8b626ea3305780sewardj 32020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (0) { 32030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("SPEC: "); 3204dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRExpr(st->Ist.WrTmp.data); 32050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" --> "); 32060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(ex); 32070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 32080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 32090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 3210b92307503d4fb9265136e182d10c42ebb9dd8272sewardj 3211b92307503d4fb9265136e182d10c42ebb9dd8272sewardj if (any) 3212b92307503d4fb9265136e182d10c42ebb9dd8272sewardj bb = flatten_BB(bb); 3213b92307503d4fb9265136e182d10c42ebb9dd8272sewardj return bb; 32142963239357452b96dbe6de1b3f8b626ea3305780sewardj} 32152963239357452b96dbe6de1b3f8b626ea3305780sewardj 32162963239357452b96dbe6de1b3f8b626ea3305780sewardj 32170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 32189b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/*--- Determination of guest state aliasing relationships ---*/ 32199b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/*---------------------------------------------------------------*/ 32209b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32219b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/* These are helper functions for CSE and GetI/PutI transformations. 32229b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32239b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Determine, to the extent possible, the relationship between two 32249b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj guest state accesses. The possible outcomes are: 32259b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32269b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj * Exact alias. These two accesses denote precisely the same 32279b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj piece of the guest state. 32289b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj * Definitely no alias. These two accesses are guaranteed not to 32309b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj overlap any part of the guest state. 32319b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32329b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj * Unknown -- if neither of the above can be established. 32339b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32349b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj If in doubt, return Unknown. */ 32359b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32369b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardjtypedef 32379b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj enum { ExactAlias, NoAlias, UnknownAlias } 32389b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj GSAliasing; 32399b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32409b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32419b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/* Produces the alias relation between an indexed guest 32429b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj state access and a non-indexed access. */ 32439b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32449b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardjstatic 3245dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjGSAliasing getAliasingRelation_IC ( IRRegArray* descr1, IRExpr* ix1, 32469b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Int offset2, IRType ty2 ) 32479b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj{ 32489b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj UInt minoff1, maxoff1, minoff2, maxoff2; 32499b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32509b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj getArrayBounds( descr1, &minoff1, &maxoff1 ); 32519b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj minoff2 = offset2; 32529b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj maxoff2 = minoff2 + sizeofIRType(ty2) - 1; 32539b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32549b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (maxoff1 < minoff2 || maxoff2 < minoff1) 32559b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return NoAlias; 32569b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32579b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* Could probably do better here if required. For the moment 32589b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj however just claim not to know anything more. */ 32599b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return UnknownAlias; 32609b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj} 32619b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32629b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32639b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/* Produces the alias relation between two indexed guest state 32649b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj accesses. */ 32659b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32669b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardjstatic 32679b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardjGSAliasing getAliasingRelation_II ( 3268dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRRegArray* descr1, IRExpr* ix1, Int bias1, 3269dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRRegArray* descr2, IRExpr* ix2, Int bias2 32709b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ) 32719b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj{ 32729b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj UInt minoff1, maxoff1, minoff2, maxoff2; 32739b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Int iters; 32749b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32759b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* First try hard to show they don't alias. */ 32769b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj getArrayBounds( descr1, &minoff1, &maxoff1 ); 32779b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj getArrayBounds( descr2, &minoff2, &maxoff2 ); 32789b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (maxoff1 < minoff2 || maxoff2 < minoff1) 32799b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return NoAlias; 32809b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32819b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* So the two arrays at least partially overlap. To get any 32829b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj further we'll have to be sure that the descriptors are 32839b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj identical. */ 3284dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (!eqIRRegArray(descr1, descr2)) 32859b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return UnknownAlias; 32869b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32879b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* The descriptors are identical. Now the only difference can be 32889b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj in the index expressions. If they cannot be shown to be 32899b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj identical, we have to say we don't know what the aliasing 32909b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj relation will be. Now, since the IR is flattened, the index 32919b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj expressions should be atoms -- either consts or tmps. So that 32929b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj makes the comparison simple. */ 32939b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(isIRAtom(ix1)); 32949b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(isIRAtom(ix2)); 32959b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (!eqIRAtom(ix1,ix2)) 32969b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return UnknownAlias; 32979b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 32989b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* Ok, the index expressions are identical. So now the only way 32999b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj they can be different is in the bias. Normalise this 33009b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj paranoidly, to reliably establish equality/non-equality. */ 33019b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 33029b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* So now we know that the GetI and PutI index the same array 33039b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj with the same base. Are the offsets the same, modulo the 33049b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj array size? Do this paranoidly. */ 33059b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(descr1->nElems == descr2->nElems); 33069b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(descr1->elemTy == descr2->elemTy); 33079b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(descr1->base == descr2->base); 33089b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj iters = 0; 33099b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj while (bias1 < 0 || bias2 < 0) { 33109b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj bias1 += descr1->nElems; 33119b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj bias2 += descr1->nElems; 33129b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj iters++; 33139b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (iters > 10) 33149b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vpanic("getAliasingRelation: iters"); 33159b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 33169b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(bias1 >= 0 && bias2 >= 0); 33179b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj bias1 %= descr1->nElems; 33189b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj bias2 %= descr1->nElems; 33199b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(bias1 >= 0 && bias1 < descr1->nElems); 33209b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(bias2 >= 0 && bias2 < descr1->nElems); 33219b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 33229b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* Finally, biasP and biasG are normalised into the range 33239b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 0 .. descrP/G->nElems - 1. And so we can establish 33249b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj equality/non-equality. */ 33259b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 33269b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return bias1==bias2 ? ExactAlias : NoAlias; 33279b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj} 33289b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 33299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 33309b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/*---------------------------------------------------------------*/ 33310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Common Subexpression Elimination ---*/ 33320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 33330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 33340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Expensive in time and space. */ 33350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 33360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Uses two environments: 33370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj a IRTemp -> IRTemp mapping 33380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj a mapping from AvailExpr* to IRTemp 33392963239357452b96dbe6de1b3f8b626ea3305780sewardj*/ 33402963239357452b96dbe6de1b3f8b626ea3305780sewardj 33410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjtypedef 33420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 3343e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj enum { TCc, TCt } tag; 3344e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj union { IRTemp tmp; IRConst* con; } u; 3345e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3346e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj TmpOrConst; 3347e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj 3348e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardjstatic Bool eqTmpOrConst ( TmpOrConst* tc1, TmpOrConst* tc2 ) 3349e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj{ 3350e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (tc1->tag != tc2->tag) 3351e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return False; 3352e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj switch (tc1->tag) { 3353e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj case TCc: 3354e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return eqIRConst(tc1->u.con, tc2->u.con); 3355e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj case TCt: 3356e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return tc1->u.tmp == tc2->u.tmp; 3357e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj default: 3358e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vpanic("eqTmpOrConst"); 3359e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3360e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj} 3361e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj 3362e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardjstatic Bool eqIRCallee ( IRCallee* cee1, IRCallee* cee2 ) 3363e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj{ 3364e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Bool eq = cee1->addr == cee2->addr; 3365e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (eq) { 3366e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vassert(cee1->regparms == cee2->regparms); 3367e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vassert(cee1->mcx_mask == cee2->mcx_mask); 3368e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj /* Names should be the same too, but we don't bother to 3369e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj check. */ 3370e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3371e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return eq; 3372e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj} 3373e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj 3374581cf07354594dc2006498f0f2d081974b579b5asewardj/* Convert an atomic IRExpr* to a TmpOrConst. */ 3375581cf07354594dc2006498f0f2d081974b579b5asewardjstatic void irExpr_to_TmpOrConst ( /*OUT*/TmpOrConst* tc, IRExpr* e ) 3376581cf07354594dc2006498f0f2d081974b579b5asewardj{ 3377581cf07354594dc2006498f0f2d081974b579b5asewardj switch (e->tag) { 3378581cf07354594dc2006498f0f2d081974b579b5asewardj case Iex_RdTmp: 3379581cf07354594dc2006498f0f2d081974b579b5asewardj tc->tag = TCt; 3380581cf07354594dc2006498f0f2d081974b579b5asewardj tc->u.tmp = e->Iex.RdTmp.tmp; 3381581cf07354594dc2006498f0f2d081974b579b5asewardj break; 3382581cf07354594dc2006498f0f2d081974b579b5asewardj case Iex_Const: 3383581cf07354594dc2006498f0f2d081974b579b5asewardj tc->tag = TCc; 3384581cf07354594dc2006498f0f2d081974b579b5asewardj tc->u.con = e->Iex.Const.con; 3385581cf07354594dc2006498f0f2d081974b579b5asewardj break; 3386581cf07354594dc2006498f0f2d081974b579b5asewardj default: 3387581cf07354594dc2006498f0f2d081974b579b5asewardj /* Getting here is a serious error. It means that the 3388581cf07354594dc2006498f0f2d081974b579b5asewardj presented arg isn't an IR atom, as it should be. */ 3389581cf07354594dc2006498f0f2d081974b579b5asewardj vpanic("irExpr_to_TmpOrConst"); 3390581cf07354594dc2006498f0f2d081974b579b5asewardj } 3391581cf07354594dc2006498f0f2d081974b579b5asewardj} 3392581cf07354594dc2006498f0f2d081974b579b5asewardj 3393581cf07354594dc2006498f0f2d081974b579b5asewardj/* Convert a TmpOrConst to an atomic IRExpr*. */ 3394581cf07354594dc2006498f0f2d081974b579b5asewardjstatic IRExpr* tmpOrConst_to_IRExpr ( TmpOrConst* tc ) 3395581cf07354594dc2006498f0f2d081974b579b5asewardj{ 3396581cf07354594dc2006498f0f2d081974b579b5asewardj switch (tc->tag) { 3397581cf07354594dc2006498f0f2d081974b579b5asewardj case TCc: return IRExpr_Const(tc->u.con); 3398581cf07354594dc2006498f0f2d081974b579b5asewardj case TCt: return IRExpr_RdTmp(tc->u.tmp); 3399581cf07354594dc2006498f0f2d081974b579b5asewardj default: vpanic("tmpOrConst_to_IRExpr"); 3400581cf07354594dc2006498f0f2d081974b579b5asewardj } 3401581cf07354594dc2006498f0f2d081974b579b5asewardj} 3402581cf07354594dc2006498f0f2d081974b579b5asewardj 3403e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj/* Convert a NULL terminated IRExpr* vector to an array of 3404e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj TmpOrConsts, and a length. */ 3405e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardjstatic void irExprVec_to_TmpOrConsts ( /*OUT*/TmpOrConst** outs, 3406e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj /*OUT*/Int* nOuts, 3407e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj IRExpr** ins ) 3408e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj{ 3409e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Int i, n; 3410e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj /* We have to make two passes, one to count, one to copy. */ 3411e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj for (n = 0; ins[n]; n++) 3412e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj ; 3413d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian *outs = LibVEX_Alloc_inline(n * sizeof(TmpOrConst)); 3414e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj *nOuts = n; 3415e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj /* and now copy .. */ 3416e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj for (i = 0; i < n; i++) { 3417581cf07354594dc2006498f0f2d081974b579b5asewardj IRExpr* arg = ins[i]; 3418e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj TmpOrConst* dst = &(*outs)[i]; 3419581cf07354594dc2006498f0f2d081974b579b5asewardj irExpr_to_TmpOrConst(dst, arg); 3420e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3421e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj} 3422e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj 3423e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardjtypedef 3424e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj struct { 3425b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian enum { Ut, Btt, Btc, Bct, Cf64i, Ittt, Itct, Ittc, Itcc, GetIt, 34262608c6946f80e733875aa4969c39740fcb012c17sewardj CCall, Load 3427da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian } tag; 34280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj union { 34290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* unop(tmp) */ 34300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 34310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IROp op; 34320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp arg; 34330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } Ut; 34340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* binop(tmp,tmp) */ 34350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 34360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IROp op; 34370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp arg1; 34380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp arg2; 34390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } Btt; 34400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* binop(tmp,const) */ 34410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 34420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IROp op; 34430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp arg1; 34440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRConst con2; 34450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } Btc; 34460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* binop(const,tmp) */ 34470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 34480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IROp op; 34490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRConst con1; 34500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp arg2; 34510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } Bct; 34520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* F64i-style const */ 34530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj struct { 34540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ULong f64i; 34550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } Cf64i; 345699dd03e04a6914d90d5fee727d61d76905334becflorian /* ITE(tmp,tmp,tmp) */ 34579b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj struct { 34589b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj IRTemp co; 3459b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRTemp e1; 34609b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj IRTemp e0; 3461b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian } Ittt; 346299dd03e04a6914d90d5fee727d61d76905334becflorian /* ITE(tmp,tmp,const) */ 3463da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian struct { 3464da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRTemp co; 3465b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRTemp e1; 3466da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRConst con0; 3467b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian } Ittc; 346899dd03e04a6914d90d5fee727d61d76905334becflorian /* ITE(tmp,const,tmp) */ 3469da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian struct { 3470da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRTemp co; 3471b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRConst con1; 3472da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRTemp e0; 3473b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian } Itct; 347499dd03e04a6914d90d5fee727d61d76905334becflorian /* ITE(tmp,const,const) */ 3475da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian struct { 3476da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRTemp co; 3477b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRConst con1; 3478da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian IRConst con0; 3479b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian } Itcc; 34809b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* GetI(descr,tmp,bias)*/ 34819b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj struct { 3482dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRRegArray* descr; 3483dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRTemp ix; 3484dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj Int bias; 34859b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } GetIt; 3486e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj /* Clean helper call */ 3487e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj struct { 3488e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj IRCallee* cee; 3489e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj TmpOrConst* args; 3490e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Int nArgs; 3491e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj IRType retty; 3492e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } CCall; 34932608c6946f80e733875aa4969c39740fcb012c17sewardj /* Load(end,ty,addr) */ 34942608c6946f80e733875aa4969c39740fcb012c17sewardj struct { 34952608c6946f80e733875aa4969c39740fcb012c17sewardj IREndness end; 34962608c6946f80e733875aa4969c39740fcb012c17sewardj IRType ty; 34972608c6946f80e733875aa4969c39740fcb012c17sewardj TmpOrConst addr; 34982608c6946f80e733875aa4969c39740fcb012c17sewardj } Load; 34990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } u; 35000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 35010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj AvailExpr; 350217442fe8094d0f82266e5a05509f62cac8f7539esewardj 35030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic Bool eq_AvailExpr ( AvailExpr* a1, AvailExpr* a2 ) 350417442fe8094d0f82266e5a05509f62cac8f7539esewardj{ 3505e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (LIKELY(a1->tag != a2->tag)) 35060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 35070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (a1->tag) { 35080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ut: 35099d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( 35109d2e769a9368d2b22c32a4764a70e9da38769628sewardj a1->u.Ut.op == a2->u.Ut.op 35119d2e769a9368d2b22c32a4764a70e9da38769628sewardj && a1->u.Ut.arg == a2->u.Ut.arg); 35120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btt: 35139d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( 35149d2e769a9368d2b22c32a4764a70e9da38769628sewardj a1->u.Btt.op == a2->u.Btt.op 35150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && a1->u.Btt.arg1 == a2->u.Btt.arg1 35169d2e769a9368d2b22c32a4764a70e9da38769628sewardj && a1->u.Btt.arg2 == a2->u.Btt.arg2); 35170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btc: 35189d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( 35199d2e769a9368d2b22c32a4764a70e9da38769628sewardj a1->u.Btc.op == a2->u.Btc.op 35200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && a1->u.Btc.arg1 == a2->u.Btc.arg1 35219d2e769a9368d2b22c32a4764a70e9da38769628sewardj && eqIRConst(&a1->u.Btc.con2, &a2->u.Btc.con2)); 35220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Bct: 35239d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( 35249d2e769a9368d2b22c32a4764a70e9da38769628sewardj a1->u.Bct.op == a2->u.Bct.op 35250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && a1->u.Bct.arg2 == a2->u.Bct.arg2 35269d2e769a9368d2b22c32a4764a70e9da38769628sewardj && eqIRConst(&a1->u.Bct.con1, &a2->u.Bct.con1)); 35270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Cf64i: 35289d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool(a1->u.Cf64i.f64i == a2->u.Cf64i.f64i); 3529b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittt: 3530b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return toBool(a1->u.Ittt.co == a2->u.Ittt.co 3531b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && a1->u.Ittt.e1 == a2->u.Ittt.e1 3532b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && a1->u.Ittt.e0 == a2->u.Ittt.e0); 3533b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittc: 3534b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return toBool(a1->u.Ittc.co == a2->u.Ittc.co 3535b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && a1->u.Ittc.e1 == a2->u.Ittc.e1 3536b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && eqIRConst(&a1->u.Ittc.con0, &a2->u.Ittc.con0)); 3537b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itct: 3538b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return toBool(a1->u.Itct.co == a2->u.Itct.co 3539b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && eqIRConst(&a1->u.Itct.con1, &a2->u.Itct.con1) 3540b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && a1->u.Itct.e0 == a2->u.Itct.e0); 3541b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itcc: 3542b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return toBool(a1->u.Itcc.co == a2->u.Itcc.co 3543b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && eqIRConst(&a1->u.Itcc.con1, &a2->u.Itcc.con1) 3544b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian && eqIRConst(&a1->u.Itcc.con0, &a2->u.Itcc.con0)); 35459b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case GetIt: 3546dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return toBool(eqIRRegArray(a1->u.GetIt.descr, a2->u.GetIt.descr) 35479b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj && a1->u.GetIt.ix == a2->u.GetIt.ix 35489b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj && a1->u.GetIt.bias == a2->u.GetIt.bias); 3549e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj case CCall: { 3550e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Int i, n; 3551e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Bool eq = a1->u.CCall.nArgs == a2->u.CCall.nArgs 3552e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj && eqIRCallee(a1->u.CCall.cee, a2->u.CCall.cee); 3553e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (eq) { 3554e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj n = a1->u.CCall.nArgs; 3555e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj for (i = 0; i < n; i++) { 3556e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (!eqTmpOrConst( &a1->u.CCall.args[i], 3557e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj &a2->u.CCall.args[i] )) { 3558e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj eq = False; 3559e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj break; 3560e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3561e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3562e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3563e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj if (eq) vassert(a1->u.CCall.retty == a2->u.CCall.retty); 3564e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return eq; 3565e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 35662608c6946f80e733875aa4969c39740fcb012c17sewardj case Load: { 35672608c6946f80e733875aa4969c39740fcb012c17sewardj Bool eq = toBool(a1->u.Load.end == a2->u.Load.end 35682608c6946f80e733875aa4969c39740fcb012c17sewardj && a1->u.Load.ty == a2->u.Load.ty 35692608c6946f80e733875aa4969c39740fcb012c17sewardj && eqTmpOrConst(&a1->u.Load.addr, &a2->u.Load.addr)); 35702608c6946f80e733875aa4969c39740fcb012c17sewardj return eq; 35712608c6946f80e733875aa4969c39740fcb012c17sewardj } 35722608c6946f80e733875aa4969c39740fcb012c17sewardj default: 35732608c6946f80e733875aa4969c39740fcb012c17sewardj vpanic("eq_AvailExpr"); 357417442fe8094d0f82266e5a05509f62cac8f7539esewardj } 357517442fe8094d0f82266e5a05509f62cac8f7539esewardj} 35762963239357452b96dbe6de1b3f8b626ea3305780sewardj 35770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic IRExpr* availExpr_to_IRExpr ( AvailExpr* ae ) 35782963239357452b96dbe6de1b3f8b626ea3305780sewardj{ 3579b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRConst *con, *con0, *con1; 35800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (ae->tag) { 35810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ut: 3582dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRExpr_Unop( ae->u.Ut.op, IRExpr_RdTmp(ae->u.Ut.arg) ); 35830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btt: 35840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Binop( ae->u.Btt.op, 3585dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.Btt.arg1), 3586dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.Btt.arg2) ); 35870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btc: 3588d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con = LibVEX_Alloc_inline(sizeof(IRConst)); 35890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *con = ae->u.Btc.con2; 35900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Binop( ae->u.Btc.op, 3591dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.Btc.arg1), 3592dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_Const(con) ); 35930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Bct: 3594d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con = LibVEX_Alloc_inline(sizeof(IRConst)); 35950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *con = ae->u.Bct.con1; 35960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Binop( ae->u.Bct.op, 3597dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_Const(con), 3598dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.Bct.arg2) ); 35990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Cf64i: 36000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_Const(IRConst_F64i(ae->u.Cf64i.f64i)); 3601b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittt: 3602b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return IRExpr_ITE(IRExpr_RdTmp(ae->u.Ittt.co), 3603b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_RdTmp(ae->u.Ittt.e1), 3604b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_RdTmp(ae->u.Ittt.e0)); 3605b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittc: 3606d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con0 = LibVEX_Alloc_inline(sizeof(IRConst)); 3607b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian *con0 = ae->u.Ittc.con0; 3608b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return IRExpr_ITE(IRExpr_RdTmp(ae->u.Ittc.co), 3609b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_RdTmp(ae->u.Ittc.e1), 361099dd03e04a6914d90d5fee727d61d76905334becflorian IRExpr_Const(con0)); 3611b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itct: 3612d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con1 = LibVEX_Alloc_inline(sizeof(IRConst)); 3613b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian *con1 = ae->u.Itct.con1; 3614b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return IRExpr_ITE(IRExpr_RdTmp(ae->u.Itct.co), 3615b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_Const(con1), 3616b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_RdTmp(ae->u.Itct.e0)); 3617b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian 3618b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itcc: 3619d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con0 = LibVEX_Alloc_inline(sizeof(IRConst)); 3620d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian con1 = LibVEX_Alloc_inline(sizeof(IRConst)); 3621b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian *con0 = ae->u.Itcc.con0; 3622b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian *con1 = ae->u.Itcc.con1; 3623b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian return IRExpr_ITE(IRExpr_RdTmp(ae->u.Itcc.co), 3624b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian IRExpr_Const(con1), 362599dd03e04a6914d90d5fee727d61d76905334becflorian IRExpr_Const(con0)); 36269b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case GetIt: 36279b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return IRExpr_GetI(ae->u.GetIt.descr, 3628dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.GetIt.ix), 36299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae->u.GetIt.bias); 3630e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj case CCall: { 3631e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Int i, n = ae->u.CCall.nArgs; 3632e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vassert(n >= 0); 3633d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian IRExpr** vec = LibVEX_Alloc_inline((n+1) * sizeof(IRExpr*)); 3634e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vec[n] = NULL; 3635e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj for (i = 0; i < n; i++) { 3636581cf07354594dc2006498f0f2d081974b579b5asewardj vec[i] = tmpOrConst_to_IRExpr(&ae->u.CCall.args[i]); 3637e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3638e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj return IRExpr_CCall(ae->u.CCall.cee, 3639e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj ae->u.CCall.retty, 3640e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj vec); 3641e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 36422608c6946f80e733875aa4969c39740fcb012c17sewardj case Load: 36432608c6946f80e733875aa4969c39740fcb012c17sewardj return IRExpr_Load(ae->u.Load.end, ae->u.Load.ty, 36442608c6946f80e733875aa4969c39740fcb012c17sewardj tmpOrConst_to_IRExpr(&ae->u.Load.addr)); 36450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 36460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("availExpr_to_IRExpr"); 36472963239357452b96dbe6de1b3f8b626ea3305780sewardj } 36482963239357452b96dbe6de1b3f8b626ea3305780sewardj} 36492963239357452b96dbe6de1b3f8b626ea3305780sewardj 36500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjinline 36510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic IRTemp subst_AvailExpr_Temp ( HashHW* env, IRTemp tmp ) 36522963239357452b96dbe6de1b3f8b626ea3305780sewardj{ 36530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HWord res; 36540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* env :: IRTemp -> IRTemp */ 36550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (lookupHHW( env, &res, (HWord)tmp )) 36560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return (IRTemp)res; 36570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 36580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return tmp; 36590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 3660f6501996bf1f0e2a8ce6817efe9edf6b619bc85bsewardj 3661581cf07354594dc2006498f0f2d081974b579b5asewardjinline 3662581cf07354594dc2006498f0f2d081974b579b5asewardjstatic void subst_AvailExpr_TmpOrConst ( /*MB_MOD*/TmpOrConst* tc, 3663581cf07354594dc2006498f0f2d081974b579b5asewardj HashHW* env ) 3664581cf07354594dc2006498f0f2d081974b579b5asewardj{ 3665581cf07354594dc2006498f0f2d081974b579b5asewardj /* env :: IRTemp -> IRTemp */ 3666581cf07354594dc2006498f0f2d081974b579b5asewardj if (tc->tag == TCt) { 3667581cf07354594dc2006498f0f2d081974b579b5asewardj tc->u.tmp = subst_AvailExpr_Temp( env, tc->u.tmp ); 3668581cf07354594dc2006498f0f2d081974b579b5asewardj } 3669581cf07354594dc2006498f0f2d081974b579b5asewardj} 3670581cf07354594dc2006498f0f2d081974b579b5asewardj 36710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void subst_AvailExpr ( HashHW* env, AvailExpr* ae ) 36720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 36730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* env :: IRTemp -> IRTemp */ 36740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (ae->tag) { 36750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ut: 36760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ae->u.Ut.arg = subst_AvailExpr_Temp( env, ae->u.Ut.arg ); 36770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 36780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btt: 36790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ae->u.Btt.arg1 = subst_AvailExpr_Temp( env, ae->u.Btt.arg1 ); 36800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ae->u.Btt.arg2 = subst_AvailExpr_Temp( env, ae->u.Btt.arg2 ); 36810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 36820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Btc: 36830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ae->u.Btc.arg1 = subst_AvailExpr_Temp( env, ae->u.Btc.arg1 ); 36840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 36850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Bct: 36860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ae->u.Bct.arg2 = subst_AvailExpr_Temp( env, ae->u.Bct.arg2 ); 36870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 36880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Cf64i: 36890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 3690b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittt: 3691b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.co = subst_AvailExpr_Temp( env, ae->u.Ittt.co ); 3692b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.e1 = subst_AvailExpr_Temp( env, ae->u.Ittt.e1 ); 3693b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.e0 = subst_AvailExpr_Temp( env, ae->u.Ittt.e0 ); 36949b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj break; 3695b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Ittc: 3696b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittc.co = subst_AvailExpr_Temp( env, ae->u.Ittc.co ); 3697b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittc.e1 = subst_AvailExpr_Temp( env, ae->u.Ittc.e1 ); 3698da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian break; 3699b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itct: 3700b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itct.co = subst_AvailExpr_Temp( env, ae->u.Itct.co ); 3701b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itct.e0 = subst_AvailExpr_Temp( env, ae->u.Itct.e0 ); 3702da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian break; 3703b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian case Itcc: 3704b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itcc.co = subst_AvailExpr_Temp( env, ae->u.Itcc.co ); 3705da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian break; 37069b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case GetIt: 37079b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae->u.GetIt.ix = subst_AvailExpr_Temp( env, ae->u.GetIt.ix ); 37089b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj break; 3709e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj case CCall: { 3710e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj Int i, n = ae->u.CCall.nArgs;; 3711e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj for (i = 0; i < n; i++) { 3712581cf07354594dc2006498f0f2d081974b579b5asewardj subst_AvailExpr_TmpOrConst(&ae->u.CCall.args[i], env); 3713e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3714e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj break; 3715e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 37162608c6946f80e733875aa4969c39740fcb012c17sewardj case Load: 37172608c6946f80e733875aa4969c39740fcb012c17sewardj subst_AvailExpr_TmpOrConst(&ae->u.Load.addr, env); 37182608c6946f80e733875aa4969c39740fcb012c17sewardj break; 37192963239357452b96dbe6de1b3f8b626ea3305780sewardj default: 37200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("subst_AvailExpr"); 37212963239357452b96dbe6de1b3f8b626ea3305780sewardj } 37222963239357452b96dbe6de1b3f8b626ea3305780sewardj} 37232963239357452b96dbe6de1b3f8b626ea3305780sewardj 37242608c6946f80e733875aa4969c39740fcb012c17sewardjstatic AvailExpr* irExpr_to_AvailExpr ( IRExpr* e, Bool allowLoadsToBeCSEd ) 37252963239357452b96dbe6de1b3f8b626ea3305780sewardj{ 37260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj AvailExpr* ae; 37270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3728c1b9e39e1a7407076cd48aa2704b398f547cb760florian switch (e->tag) { 3729c1b9e39e1a7407076cd48aa2704b398f547cb760florian case Iex_Unop: 3730c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.Unop.arg->tag == Iex_RdTmp) { 3731d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3732c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = Ut; 3733c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Ut.op = e->Iex.Unop.op; 3734c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Ut.arg = e->Iex.Unop.arg->Iex.RdTmp.tmp; 3735c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3736c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3737c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 37380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3739c1b9e39e1a7407076cd48aa2704b398f547cb760florian case Iex_Binop: 3740c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.Binop.arg1->tag == Iex_RdTmp) { 3741c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.Binop.arg2->tag == Iex_RdTmp) { 3742d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3743c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = Btt; 3744c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btt.op = e->Iex.Binop.op; 3745c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btt.arg1 = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 3746c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btt.arg2 = e->Iex.Binop.arg2->Iex.RdTmp.tmp; 3747c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3748c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3749c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.Binop.arg2->tag == Iex_Const) { 3750d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3751c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = Btc; 3752c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btc.op = e->Iex.Binop.op; 3753c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btc.arg1 = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 3754c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Btc.con2 = *(e->Iex.Binop.arg2->Iex.Const.con); 3755c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3756c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3757c1b9e39e1a7407076cd48aa2704b398f547cb760florian } else if (e->Iex.Binop.arg1->tag == Iex_Const 3758c1b9e39e1a7407076cd48aa2704b398f547cb760florian && e->Iex.Binop.arg2->tag == Iex_RdTmp) { 3759d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3760c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = Bct; 3761c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Bct.op = e->Iex.Binop.op; 3762c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Bct.arg2 = e->Iex.Binop.arg2->Iex.RdTmp.tmp; 3763c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Bct.con1 = *(e->Iex.Binop.arg1->Iex.Const.con); 3764c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3765c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3766c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 37679b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 3768c1b9e39e1a7407076cd48aa2704b398f547cb760florian case Iex_Const: 3769c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.Const.con->tag == Ico_F64i) { 3770d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3771c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = Cf64i; 3772c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.Cf64i.f64i = e->Iex.Const.con->Ico.F64i; 3773c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3774c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3775c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 3776da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian 377799dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 377899dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.cond->tag == Iex_RdTmp) { 377999dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.iffalse->tag == Iex_RdTmp) { 378099dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.iftrue->tag == Iex_RdTmp) { 3781d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3782b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->tag = Ittt; 3783b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.co = e->Iex.ITE.cond->Iex.RdTmp.tmp; 3784b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.e1 = e->Iex.ITE.iftrue->Iex.RdTmp.tmp; 3785b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittt.e0 = e->Iex.ITE.iffalse->Iex.RdTmp.tmp; 3786c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3787c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 378899dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.iftrue->tag == Iex_Const) { 3789d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3790b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->tag = Itct; 3791b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itct.co = e->Iex.ITE.cond->Iex.RdTmp.tmp; 3792b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itct.con1 = *(e->Iex.ITE.iftrue->Iex.Const.con); 3793b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itct.e0 = e->Iex.ITE.iffalse->Iex.RdTmp.tmp; 3794c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3795c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 379699dd03e04a6914d90d5fee727d61d76905334becflorian } else if (e->Iex.ITE.iffalse->tag == Iex_Const) { 379799dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.iftrue->tag == Iex_RdTmp) { 3798d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3799b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->tag = Ittc; 3800b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittc.co = e->Iex.ITE.cond->Iex.RdTmp.tmp; 3801b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittc.e1 = e->Iex.ITE.iftrue->Iex.RdTmp.tmp; 3802b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Ittc.con0 = *(e->Iex.ITE.iffalse->Iex.Const.con); 3803c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3804c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 380599dd03e04a6914d90d5fee727d61d76905334becflorian if (e->Iex.ITE.iftrue->tag == Iex_Const) { 3806d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3807b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->tag = Itcc; 3808b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itcc.co = e->Iex.ITE.cond->Iex.RdTmp.tmp; 3809b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itcc.con1 = *(e->Iex.ITE.iftrue->Iex.Const.con); 3810b05c20c80c7e76e2f2ef82eb7806672967638d6cflorian ae->u.Itcc.con0 = *(e->Iex.ITE.iffalse->Iex.Const.con); 3811c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3812c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3813c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3814c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3815c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 3816da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian 3817c1b9e39e1a7407076cd48aa2704b398f547cb760florian case Iex_GetI: 3818c1b9e39e1a7407076cd48aa2704b398f547cb760florian if (e->Iex.GetI.ix->tag == Iex_RdTmp) { 3819d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3820c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = GetIt; 3821c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.GetIt.descr = e->Iex.GetI.descr; 3822c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.GetIt.ix = e->Iex.GetI.ix->Iex.RdTmp.tmp; 3823c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.GetIt.bias = e->Iex.GetI.bias; 3824c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 3825c1b9e39e1a7407076cd48aa2704b398f547cb760florian } 3826c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 3827da25eddcd3cf7661eb6c851b96d5431cc9f7773bflorian 3828c1b9e39e1a7407076cd48aa2704b398f547cb760florian case Iex_CCall: 3829d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 3830c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->tag = CCall; 3831c1b9e39e1a7407076cd48aa2704b398f547cb760florian /* Ok to share only the cee, since it is immutable. */ 3832c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.CCall.cee = e->Iex.CCall.cee; 3833c1b9e39e1a7407076cd48aa2704b398f547cb760florian ae->u.CCall.retty = e->Iex.CCall.retty; 3834c1b9e39e1a7407076cd48aa2704b398f547cb760florian /* irExprVec_to_TmpOrConsts will assert if the args are 3835c1b9e39e1a7407076cd48aa2704b398f547cb760florian neither tmps nor constants, but that's ok .. that's all they 3836c1b9e39e1a7407076cd48aa2704b398f547cb760florian should be. */ 3837c1b9e39e1a7407076cd48aa2704b398f547cb760florian irExprVec_to_TmpOrConsts( 3838c1b9e39e1a7407076cd48aa2704b398f547cb760florian &ae->u.CCall.args, &ae->u.CCall.nArgs, 3839c1b9e39e1a7407076cd48aa2704b398f547cb760florian e->Iex.CCall.args 3840c1b9e39e1a7407076cd48aa2704b398f547cb760florian ); 3841c1b9e39e1a7407076cd48aa2704b398f547cb760florian return ae; 38429b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 38432608c6946f80e733875aa4969c39740fcb012c17sewardj case Iex_Load: 38442608c6946f80e733875aa4969c39740fcb012c17sewardj /* If the caller of do_cse_BB has requested that loads also 38452608c6946f80e733875aa4969c39740fcb012c17sewardj be CSEd, convert them into AvailExprs. If not, we'll just 38462608c6946f80e733875aa4969c39740fcb012c17sewardj return NULL here, and the load never becomes considered 38472608c6946f80e733875aa4969c39740fcb012c17sewardj "available", which effectively disables CSEing of them, as 38482608c6946f80e733875aa4969c39740fcb012c17sewardj desired. */ 38492608c6946f80e733875aa4969c39740fcb012c17sewardj if (allowLoadsToBeCSEd) { 3850d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian ae = LibVEX_Alloc_inline(sizeof(AvailExpr)); 38512608c6946f80e733875aa4969c39740fcb012c17sewardj ae->tag = Load; 38522608c6946f80e733875aa4969c39740fcb012c17sewardj ae->u.Load.end = e->Iex.Load.end; 38532608c6946f80e733875aa4969c39740fcb012c17sewardj ae->u.Load.ty = e->Iex.Load.ty; 38542608c6946f80e733875aa4969c39740fcb012c17sewardj irExpr_to_TmpOrConst(&ae->u.Load.addr, e->Iex.Load.addr); 38552608c6946f80e733875aa4969c39740fcb012c17sewardj return ae; 38562608c6946f80e733875aa4969c39740fcb012c17sewardj } 38572608c6946f80e733875aa4969c39740fcb012c17sewardj break; 38582608c6946f80e733875aa4969c39740fcb012c17sewardj 3859c1b9e39e1a7407076cd48aa2704b398f547cb760florian default: 3860c1b9e39e1a7407076cd48aa2704b398f547cb760florian break; 3861e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj } 3862e85780480665d1a4c2d5f4b13db4f56adec97bf9sewardj 38630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 38642963239357452b96dbe6de1b3f8b626ea3305780sewardj} 38652963239357452b96dbe6de1b3f8b626ea3305780sewardj 38662963239357452b96dbe6de1b3f8b626ea3305780sewardj 38679b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj/* The BB is modified in-place. Returns True if any changes were 38682608c6946f80e733875aa4969c39740fcb012c17sewardj made. The caller can choose whether or not loads should be CSEd. 38692608c6946f80e733875aa4969c39740fcb012c17sewardj In the normal course of things we don't do that, since CSEing loads 38702608c6946f80e733875aa4969c39740fcb012c17sewardj is something of a dodgy proposition if the guest program is doing 38712608c6946f80e733875aa4969c39740fcb012c17sewardj some screwy stuff to do with races and spinloops. */ 38720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 38732608c6946f80e733875aa4969c39740fcb012c17sewardjstatic Bool do_cse_BB ( IRSB* bb, Bool allowLoadsToBeCSEd ) 38742963239357452b96dbe6de1b3f8b626ea3305780sewardj{ 38759b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Int i, j, paranoia; 38760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp t, q; 38770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 38780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj AvailExpr* eprime; 38799b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj AvailExpr* ae; 38809b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Bool invalidate; 38819b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Bool anyDone = False; 38822963239357452b96dbe6de1b3f8b626ea3305780sewardj 38830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HashHW* tenv = newHHW(); /* :: IRTemp -> IRTemp */ 38840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj HashHW* aenv = newHHW(); /* :: AvailExpr* -> IRTemp */ 38852963239357452b96dbe6de1b3f8b626ea3305780sewardj 38860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(sizeof(IRTemp) <= sizeof(HWord)); 38872963239357452b96dbe6de1b3f8b626ea3305780sewardj 3888dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (0) { ppIRSB(bb); vex_printf("\n\n"); } 38892963239357452b96dbe6de1b3f8b626ea3305780sewardj 38900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Iterate forwards over the stmts. 3891cfe046e178666280b87da998b1b52ecda03ecd89sewardj On seeing "t = E", where E is one of the AvailExpr forms: 38920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj let E' = apply tenv substitution to E 38930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj search aenv for E' 38940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if a mapping E' -> q is found, 38950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj replace this stmt by "t = q" 38960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj and add binding t -> q to tenv 38970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 38980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj add binding E' -> t to aenv 38990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj replace this stmt by "t = E'" 39009b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 39019b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Other statements are only interesting to the extent that they 39029b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj might invalidate some of the expressions in aenv. So there is 39039b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj an invalidate-bindings check for each statement seen. 39040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 39050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb->stmts_used; i++) { 39060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 39070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 39089b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* ------ BEGIN invalidate aenv bindings ------ */ 39099b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* This is critical: remove from aenv any E' -> .. bindings 39109b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj which might be invalidated by this statement. The only 39112608c6946f80e733875aa4969c39740fcb012c17sewardj vulnerable kind of bindings are the GetI and Load kinds. 39129b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Dirty call - dump (paranoia level -> 2) 39139b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Store - dump (ditto) 39149b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Put, PutI - dump unless no-overlap is proven (.. -> 1) 39159b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Uses getAliasingRelation_IC and getAliasingRelation_II 39169b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj to do the no-overlap assessments needed for Put/PutI. 39179b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj */ 39189b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj switch (st->tag) { 3919e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_Dirty: case Ist_Store: case Ist_MBE: 3920e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_CAS: case Ist_LLSC: 3921cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: 39229b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj paranoia = 2; break; 39239b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case Ist_Put: case Ist_PutI: 39249b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj paranoia = 1; break; 39259b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case Ist_NoOp: case Ist_IMark: case Ist_AbiHint: 3926cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_WrTmp: case Ist_Exit: case Ist_LoadG: 39279b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj paranoia = 0; break; 39289b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj default: 39299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vpanic("do_cse_BB(1)"); 39309b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 39319b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 39329b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (paranoia > 0) { 39339b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj for (j = 0; j < aenv->used; j++) { 39349b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (!aenv->inuse[j]) 39359b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj continue; 39369b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae = (AvailExpr*)aenv->key[j]; 39372608c6946f80e733875aa4969c39740fcb012c17sewardj if (ae->tag != GetIt && ae->tag != Load) 39389b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj continue; 39399b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj invalidate = False; 39409b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (paranoia >= 2) { 39419b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj invalidate = True; 39429b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } else { 39439b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vassert(paranoia == 1); 39442608c6946f80e733875aa4969c39740fcb012c17sewardj if (ae->tag == Load) { 39452608c6946f80e733875aa4969c39740fcb012c17sewardj /* Loads can be invalidated by anything that could 39462608c6946f80e733875aa4969c39740fcb012c17sewardj possibly touch memory. But in that case we 39472608c6946f80e733875aa4969c39740fcb012c17sewardj should have |paranoia| == 2 and we won't get 39482608c6946f80e733875aa4969c39740fcb012c17sewardj here. So there's nothing to do; we don't have to 39492608c6946f80e733875aa4969c39740fcb012c17sewardj invalidate the load. */ 39502608c6946f80e733875aa4969c39740fcb012c17sewardj } 39512608c6946f80e733875aa4969c39740fcb012c17sewardj else 39529b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (st->tag == Ist_Put) { 39539b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (getAliasingRelation_IC( 39549b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae->u.GetIt.descr, 3955dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.GetIt.ix), 39569b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj st->Ist.Put.offset, 39579b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj typeOfIRExpr(bb->tyenv,st->Ist.Put.data) 39589b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ) != NoAlias) 39599b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj invalidate = True; 39609b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 39619b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj else 39629b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (st->tag == Ist_PutI) { 3963d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *puti = st->Ist.PutI.details; 39649b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (getAliasingRelation_II( 39659b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae->u.GetIt.descr, 3966dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(ae->u.GetIt.ix), 39679b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ae->u.GetIt.bias, 3968d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->descr, 3969d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->ix, 3970d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->bias 39719b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj ) != NoAlias) 39729b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj invalidate = True; 39739b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 39749b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj else 39759b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj vpanic("do_cse_BB(2)"); 39769b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 39779b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 39789b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (invalidate) { 39799b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj aenv->inuse[j] = False; 39809b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj aenv->key[j] = (HWord)NULL; /* be sure */ 39819b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } 39829b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } /* for j */ 39839b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj } /* paranoia > 0 */ 39849b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 39859b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* ------ ENV invalidate aenv bindings ------ */ 39869b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj 39870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* ignore not-interestings */ 3988dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag != Ist_WrTmp) 39890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 39900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 3991dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj t = st->Ist.WrTmp.tmp; 39922608c6946f80e733875aa4969c39740fcb012c17sewardj eprime = irExpr_to_AvailExpr(st->Ist.WrTmp.data, allowLoadsToBeCSEd); 39930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* ignore if not of AvailExpr form */ 39940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (!eprime) 39950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 39960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 39970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* vex_printf("considering: " ); ppIRStmt(st); vex_printf("\n"); */ 39980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 39990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* apply tenv */ 40000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj subst_AvailExpr( tenv, eprime ); 40010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 40020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* search aenv for eprime, unfortunately the hard way */ 40030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 0; j < aenv->used; j++) 40040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (aenv->inuse[j] && eq_AvailExpr(eprime, (AvailExpr*)aenv->key[j])) 40050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 40062963239357452b96dbe6de1b3f8b626ea3305780sewardj 40070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (j < aenv->used) { 40080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* A binding E' -> q was found. Replace stmt by "t = q" and 40090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj note the t->q binding in tenv. */ 40100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* (this is the core of the CSE action) */ 40110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj q = (IRTemp)aenv->val[j]; 4012dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[i] = IRStmt_WrTmp( t, IRExpr_RdTmp(q) ); 40130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addToHHW( tenv, (HWord)t, (HWord)q ); 40149b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj anyDone = True; 40150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 40160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* No binding was found, so instead we add E' -> t to our 40170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj collection of available expressions, replace this stmt 40180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj with "t = E'", and move on. */ 4019dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[i] = IRStmt_WrTmp( t, availExpr_to_IRExpr(eprime) ); 40200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj addToHHW( aenv, (HWord)eprime, (HWord)t ); 40210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 40220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 40230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 4024b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj /* 4025dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 4026dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj sanityCheckIRSB(bb, Ity_I32); 4027b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj vex_printf("\n\n"); 4028b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj */ 40299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj return anyDone; 40302963239357452b96dbe6de1b3f8b626ea3305780sewardj} 40312963239357452b96dbe6de1b3f8b626ea3305780sewardj 40322963239357452b96dbe6de1b3f8b626ea3305780sewardj 40330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 40340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Add32/Sub32 chain collapsing ---*/ 40350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 40362963239357452b96dbe6de1b3f8b626ea3305780sewardj 40370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* ----- Helper functions for Add32/Sub32 chain collapsing ----- */ 40382963239357452b96dbe6de1b3f8b626ea3305780sewardj 40390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Is this expression "Add32(tmp,const)" or "Sub32(tmp,const)" ? If 40400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj yes, set *tmp and *i32 appropriately. *i32 is set as if the 40410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj root node is Add32, not Sub32. */ 4042c9ad1158a723378c239d80ef2b53dace839d6c0esewardj 40430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic Bool isAdd32OrSub32 ( IRExpr* e, IRTemp* tmp, Int* i32 ) 40440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 40450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e->tag != Iex_Binop) 40460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 40470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e->Iex.Binop.op != Iop_Add32 && e->Iex.Binop.op != Iop_Sub32) 40480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 4049dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (e->Iex.Binop.arg1->tag != Iex_RdTmp) 40500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 40510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e->Iex.Binop.arg2->tag != Iex_Const) 40520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 4053dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj *tmp = e->Iex.Binop.arg1->Iex.RdTmp.tmp; 40540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *i32 = (Int)(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32); 40550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (e->Iex.Binop.op == Iop_Sub32) 40560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *i32 = -*i32; 40570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return True; 40580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 40592963239357452b96dbe6de1b3f8b626ea3305780sewardj 40602963239357452b96dbe6de1b3f8b626ea3305780sewardj 40610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Figure out if tmp can be expressed as tmp2 +32 const, for some 40620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj other tmp2. Scan backwards from the specified start point -- an 40630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj optimisation. */ 40642963239357452b96dbe6de1b3f8b626ea3305780sewardj 4065dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic Bool collapseChain ( IRSB* bb, Int startHere, 40660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp tmp, 40670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp* tmp2, Int* i32 ) 40680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 40690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int j, ii; 40700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp vv; 40710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 40720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* e; 40732963239357452b96dbe6de1b3f8b626ea3305780sewardj 40740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* the (var, con) pair contain the current 'representation' for 40750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 'tmp'. We start with 'tmp + 0'. */ 40760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp var = tmp; 40770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int con = 0; 40782963239357452b96dbe6de1b3f8b626ea3305780sewardj 40790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Scan backwards to see if tmp can be replaced by some other tmp 40800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj +/- a constant. */ 40810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = startHere; j >= 0; j--) { 40820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[j]; 4083dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag != Ist_WrTmp) 40842963239357452b96dbe6de1b3f8b626ea3305780sewardj continue; 4085dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->Ist.WrTmp.tmp != var) 40862963239357452b96dbe6de1b3f8b626ea3305780sewardj continue; 4087dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e = st->Ist.WrTmp.data; 40880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (!isAdd32OrSub32(e, &vv, &ii)) 40890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 40900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj var = vv; 40910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con += ii; 40922963239357452b96dbe6de1b3f8b626ea3305780sewardj } 40930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (j == -1) 40940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* no earlier binding for var .. ill-formed IR */ 40950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("collapseChain"); 40962963239357452b96dbe6de1b3f8b626ea3305780sewardj 40970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* so, did we find anything interesting? */ 40980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (var == tmp) 40990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; /* no .. */ 41000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 41010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *tmp2 = var; 41020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *i32 = con; 41030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return True; 41040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 41052963239357452b96dbe6de1b3f8b626ea3305780sewardj 41062963239357452b96dbe6de1b3f8b626ea3305780sewardj 41070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* ------- Main function for Add32/Sub32 chain collapsing ------ */ 41082963239357452b96dbe6de1b3f8b626ea3305780sewardj 4109dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic void collapse_AddSub_chains_BB ( IRSB* bb ) 41100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 41110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt *st; 41120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTemp var, var2; 41130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i, con, con2; 41142963239357452b96dbe6de1b3f8b626ea3305780sewardj 41150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb->stmts_used-1; i >= 0; i--) { 41162963239357452b96dbe6de1b3f8b626ea3305780sewardj st = bb->stmts[i]; 41178bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 41182963239357452b96dbe6de1b3f8b626ea3305780sewardj continue; 41192963239357452b96dbe6de1b3f8b626ea3305780sewardj 41200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Try to collapse 't1 = Add32/Sub32(t2, con)'. */ 41212963239357452b96dbe6de1b3f8b626ea3305780sewardj 4122dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp 4123dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && isAdd32OrSub32(st->Ist.WrTmp.data, &var, &con)) { 41242963239357452b96dbe6de1b3f8b626ea3305780sewardj 41250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* So e1 is of the form Add32(var,con) or Sub32(var,-con). 41260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Find out if var can be expressed as var2 + con2. */ 41270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (collapseChain(bb, i-1, var, &var2, &con2)) { 41280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("replacing1 "); 41300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 41310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" with "); 41320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 41330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con2 += con; 41340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts[i] 4135dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj = IRStmt_WrTmp( 4136dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj st->Ist.WrTmp.tmp, 41370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (con2 >= 0) 41380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? IRExpr_Binop(Iop_Add32, 4139dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(var2), 41400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr_Const(IRConst_U32(con2))) 41410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj : IRExpr_Binop(Iop_Sub32, 4142dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(var2), 41430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr_Const(IRConst_U32(-con2))) 41440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 41450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(bb->stmts[i]); 41470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 41480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 41490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 41502963239357452b96dbe6de1b3f8b626ea3305780sewardj 41510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 41520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 41530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 41540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Try to collapse 't1 = GetI[t2, con]'. */ 41550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 4156dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp 4157dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && st->Ist.WrTmp.data->tag == Iex_GetI 4158dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && st->Ist.WrTmp.data->Iex.GetI.ix->tag == Iex_RdTmp 4159dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && collapseChain(bb, i-1, st->Ist.WrTmp.data->Iex.GetI.ix 4160dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ->Iex.RdTmp.tmp, &var2, &con2)) { 41610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("replacing3 "); 41630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 41640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" with "); 41650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4166dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj con2 += st->Ist.WrTmp.data->Iex.GetI.bias; 41670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts[i] 4168dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj = IRStmt_WrTmp( 4169dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj st->Ist.WrTmp.tmp, 4170dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_GetI(st->Ist.WrTmp.data->Iex.GetI.descr, 4171dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr_RdTmp(var2), 41720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con2)); 41730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(bb->stmts[i]); 41750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 41760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 41770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 41782963239357452b96dbe6de1b3f8b626ea3305780sewardj } 41792963239357452b96dbe6de1b3f8b626ea3305780sewardj 41800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Perhaps st is PutI[t, con] ? */ 4181d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *puti = st->Ist.PutI.details; 41820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_PutI 4183d6f38b3f822f7d57adfc0da3410995d85d6a4597florian && puti->ix->tag == Iex_RdTmp 4184d6f38b3f822f7d57adfc0da3410995d85d6a4597florian && collapseChain(bb, i-1, puti->ix->Iex.RdTmp.tmp, 41850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj &var2, &con2)) { 41860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("replacing2 "); 41880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 41890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" with "); 41900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4191d6f38b3f822f7d57adfc0da3410995d85d6a4597florian con2 += puti->bias; 41920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts[i] 4193d6f38b3f822f7d57adfc0da3410995d85d6a4597florian = IRStmt_PutI(mkIRPutI(puti->descr, 4194d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRExpr_RdTmp(var2), 4195d6f38b3f822f7d57adfc0da3410995d85d6a4597florian con2, 4196d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->data)); 41970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 41980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(bb->stmts[i]); 41990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 42000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 42010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 42020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 42032963239357452b96dbe6de1b3f8b626ea3305780sewardj 42040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* for */ 42052963239357452b96dbe6de1b3f8b626ea3305780sewardj} 42062963239357452b96dbe6de1b3f8b626ea3305780sewardj 42072963239357452b96dbe6de1b3f8b626ea3305780sewardj 4208f0e431671cb877601c2f2e551f42246469b4ee62sewardj/*---------------------------------------------------------------*/ 42090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- PutI/GetI transformations ---*/ 42104345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj/*---------------------------------------------------------------*/ 42114345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Given the parts (descr, tmp, bias) for a GetI, scan backwards from 42130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj the given starting point to find, if any, a PutI which writes 42140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj exactly the same piece of guest state, and so return the expression 42150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj that the PutI writes. This is the core of PutI-GetI forwarding. */ 42160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 42170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic 4218dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjIRExpr* findPutI ( IRSB* bb, Int startHere, 4219dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRRegArray* descrG, IRExpr* ixG, Int biasG ) 42204345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj{ 42210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int j; 42220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 42230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj GSAliasing relation; 42244345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (0) { 42260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\nfindPutI "); 4227dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRRegArray(descrG); 42280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" "); 42290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(ixG); 42300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" %d\n", biasG); 42314345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj } 42324345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Scan backwards in bb from startHere to find a suitable PutI 42340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj binding for (descrG, ixG, biasG), if any. */ 42354345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = startHere; j >= 0; j--) { 42370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[j]; 42388bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 42398bee6d15808653a71717c256a3abe96993439d25sewardj continue; 42404345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Put) { 42420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Non-indexed Put. This can't give a binding, but we do 42430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj need to check it doesn't invalidate the search by 42440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj overlapping any part of the indexed guest state. */ 4245c0b42285bc4b9aad872fbdd813b073eabc8d74basewardj 42460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation 42470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj = getAliasingRelation_IC( 42480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj descrG, ixG, 42490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st->Ist.Put.offset, 42500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj typeOfIRExpr(bb->tyenv,st->Ist.Put.data) ); 42518f31b3ba52f176a03faba5647aba6570bdeadba9sewardj 42520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (relation == NoAlias) { 42530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* we're OK; keep going */ 42540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 42550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 42560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* relation == UnknownAlias || relation == ExactAlias */ 42570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* If this assertion fails, we've found a Put which writes 42580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj an area of guest state which is read by a GetI. Which 42590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj is unlikely (although not per se wrong). */ 42600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(relation != ExactAlias); 42610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* This Put potentially writes guest state that the GetI 42620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj reads; we must fail. */ 42630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 42640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 42650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 42664345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_PutI) { 4268d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *puti = st->Ist.PutI.details; 42694345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation = getAliasingRelation_II( 42710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj descrG, ixG, biasG, 4272d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->descr, 4273d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->ix, 4274d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->bias 42750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 42764345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (relation == NoAlias) { 42780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* This PutI definitely doesn't overlap. Ignore it and 42790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj keep going. */ 42800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; /* the for j loop */ 42810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 42824345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (relation == UnknownAlias) { 42840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* We don't know if this PutI writes to the same guest 42850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj state that the GetI, or not. So we have to give up. */ 42860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 42870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4288ea602bc23ecabe934348ef9ea4113a22d4e0bb80sewardj 42890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Otherwise, we've found what we're looking for. */ 42900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(relation == ExactAlias); 4291d6f38b3f822f7d57adfc0da3410995d85d6a4597florian return puti->data; 42924345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* if (st->tag == Ist_PutI) */ 42944345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 42950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Dirty) { 42960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Be conservative. If the dirty call has any guest effects at 42970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj all, give up. We could do better -- only give up if there 42980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj are any guest writes/modifies. */ 42990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->Ist.Dirty.details->nFxState > 0) 43000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 43010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 43024345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* for */ 43044345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* No valid replacement was found. */ 43060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 43070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 43084345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43094345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43104345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Assuming pi is a PutI stmt, is s2 identical to it (in the sense 43120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj that it writes exactly the same piece of guest state) ? Safe 43130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj answer: False. */ 43144345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 43150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic Bool identicalPutIs ( IRStmt* pi, IRStmt* s2 ) 43160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 43170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(pi->tag == Ist_PutI); 43180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (s2->tag != Ist_PutI) 43190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 43204345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 4321d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *p1 = pi->Ist.PutI.details; 4322d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *p2 = s2->Ist.PutI.details; 4323d6f38b3f822f7d57adfc0da3410995d85d6a4597florian 43249d2e769a9368d2b22c32a4764a70e9da38769628sewardj return toBool( 43259d2e769a9368d2b22c32a4764a70e9da38769628sewardj getAliasingRelation_II( 4326d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p1->descr, p1->ix, p1->bias, 4327d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p2->descr, p2->ix, p2->bias 43280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ) 43299d2e769a9368d2b22c32a4764a70e9da38769628sewardj == ExactAlias 43309d2e769a9368d2b22c32a4764a70e9da38769628sewardj ); 43314345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj} 43324345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 4333a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 43340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Assuming pi is a PutI stmt, is s2 a Get/GetI/Put/PutI which might 43350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj overlap it? Safe answer: True. Note, we could do a lot better 43360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj than this if needed. */ 4337728c9d59db14f528e3d47a5c2bf2027407ea133esewardj 43380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic 43390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjBool guestAccessWhichMightOverlapPutI ( 43400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRTypeEnv* tyenv, IRStmt* pi, IRStmt* s2 43410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ) 43420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 43430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj GSAliasing relation; 43440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj UInt minoffP, maxoffP; 43450ec972d3d99377267d6ba990045f6db970363047sewardj 43460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(pi->tag == Ist_PutI); 4347d6f38b3f822f7d57adfc0da3410995d85d6a4597florian 4348d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *p1 = pi->Ist.PutI.details; 4349d6f38b3f822f7d57adfc0da3410995d85d6a4597florian 4350d6f38b3f822f7d57adfc0da3410995d85d6a4597florian getArrayBounds(p1->descr, &minoffP, &maxoffP); 43510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (s2->tag) { 4352a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4353d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 4354f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 4355f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj return False; 4356f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj 4357c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 43585a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 43595a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj /* just be paranoid ... these should be rare. */ 4360bb3f52db829c572ec04002392e8a5056b63affb3sewardj return True; 4361bb3f52db829c572ec04002392e8a5056b63affb3sewardj 4362e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 4363e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* This is unbelievably lame, but it's probably not 4364e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj significant from a performance point of view. Really, a 4365e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj CAS is a load-store op, so it should be safe to say False. 4366e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj However .. */ 4367e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return True; 4368e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 43690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: 43700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* If the dirty call has any guest effects at all, give up. 43710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Probably could do better. */ 43720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (s2->Ist.Dirty.details->nFxState > 0) 43730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return True; 43740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 4375728c9d59db14f528e3d47a5c2bf2027407ea133esewardj 43760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 4377496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(s2->Ist.Put.data)); 43780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation 43790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj = getAliasingRelation_IC( 4380d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p1->descr, p1->ix, 43810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj s2->Ist.Put.offset, 43820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj typeOfIRExpr(tyenv,s2->Ist.Put.data) 43830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 43840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto have_relation; 4385a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4386d6f38b3f822f7d57adfc0da3410995d85d6a4597florian case Ist_PutI: { 4387d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *p2 = s2->Ist.PutI.details; 4388d6f38b3f822f7d57adfc0da3410995d85d6a4597florian 4389d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(p2->ix)); 4390d6f38b3f822f7d57adfc0da3410995d85d6a4597florian vassert(isIRAtom(p2->data)); 43910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation 43920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj = getAliasingRelation_II( 4393d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p1->descr, p1->ix, p1->bias, 4394d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p2->descr, p2->ix, p2->bias 43950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 43960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto have_relation; 4397d6f38b3f822f7d57adfc0da3410995d85d6a4597florian } 4398a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4399dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 4400dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (s2->Ist.WrTmp.data->tag == Iex_GetI) { 44010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation 44020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj = getAliasingRelation_II( 4403d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p1->descr, p1->ix, p1->bias, 4404dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj s2->Ist.WrTmp.data->Iex.GetI.descr, 4405dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj s2->Ist.WrTmp.data->Iex.GetI.ix, 4406dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj s2->Ist.WrTmp.data->Iex.GetI.bias 44070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 44080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto have_relation; 44090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4410dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (s2->Ist.WrTmp.data->tag == Iex_Get) { 44110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj relation 44120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj = getAliasingRelation_IC( 4413d6f38b3f822f7d57adfc0da3410995d85d6a4597florian p1->descr, p1->ix, 4414dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj s2->Ist.WrTmp.data->Iex.Get.offset, 4415dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj s2->Ist.WrTmp.data->Iex.Get.ty 44160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 44170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto have_relation; 44180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 44190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 4420a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4421af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 4422af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(s2->Ist.Store.addr)); 4423af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(s2->Ist.Store.data)); 44240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 4425a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 44260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 44270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRStmt(s2); vex_printf("\n"); 44280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("guestAccessWhichMightOverlapPutI"); 4429a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj } 4430a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 44310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj have_relation: 44320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (relation == NoAlias) 44330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return False; 44340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj else 44350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return True; /* ExactAlias or UnknownAlias */ 4436a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj} 4437a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4438a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4439575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 44400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* ---------- PutI/GetI transformations main functions --------- */ 44410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 44420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Remove redundant GetIs, to the extent that they can be detected. 44430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb is modified in-place. */ 44440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 44450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic 4446dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjvoid do_redundant_GetI_elimination ( IRSB* bb ) 4447575670caec4ae3cb4f3b9395fc9a9837b12432besewardj{ 44480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 44490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 4450575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4451575670caec4ae3cb4f3b9395fc9a9837b12432besewardj for (i = bb->stmts_used-1; i >= 0; i--) { 4452575670caec4ae3cb4f3b9395fc9a9837b12432besewardj st = bb->stmts[i]; 44538bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 4454575670caec4ae3cb4f3b9395fc9a9837b12432besewardj continue; 4455575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4456dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp 4457dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && st->Ist.WrTmp.data->tag == Iex_GetI 4458dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj && st->Ist.WrTmp.data->Iex.GetI.ix->tag == Iex_RdTmp) { 4459dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRRegArray* descr = st->Ist.WrTmp.data->Iex.GetI.descr; 4460dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr* ix = st->Ist.WrTmp.data->Iex.GetI.ix; 4461dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj Int bias = st->Ist.WrTmp.data->Iex.GetI.bias; 4462dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRExpr* replacement = findPutI(bb, i-1, descr, ix, bias); 44630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (replacement 4464496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj && isIRAtom(replacement) 44650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Make sure we're doing a type-safe transformation! */ 44660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && typeOfIRExpr(bb->tyenv, replacement) == descr->elemTy) { 4467575670caec4ae3cb4f3b9395fc9a9837b12432besewardj if (DEBUG_IROPT) { 44680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("rGI: "); 4469dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRExpr(st->Ist.WrTmp.data); 44700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf(" -> "); 44710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRExpr(replacement); 4472575670caec4ae3cb4f3b9395fc9a9837b12432besewardj vex_printf("\n"); 4473575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 4474dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[i] = IRStmt_WrTmp(st->Ist.WrTmp.tmp, replacement); 4475575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 4476575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 44770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4478575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 44790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 4480575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4481575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 44820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Remove redundant PutIs, to the extent which they can be detected. 44830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb is modified in-place. */ 4484575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 44850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic 4486ca2c3c75784d35d136fc7c952717cdee5063c193sewardjvoid do_redundant_PutI_elimination ( IRSB* bb, VexRegisterUpdates pxControl ) 44870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 44880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i, j; 44890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool delete; 44900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt *st, *stj; 44910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 4492ca2c3c75784d35d136fc7c952717cdee5063c193sewardj vassert(pxControl < VexRegUpdAllregsAtEachInsn); 4493c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe 44940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb->stmts_used; i++) { 44950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 44968bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag != Ist_PutI) 44970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 44980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Ok, search forwards from here to see if we can find another 44990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj PutI which makes this one redundant, and dodging various 45000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj hazards. Search forwards: 45010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If conditional exit, give up (because anything after that 45020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj does not postdominate this put). 45030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If a Get which might overlap, give up (because this PutI 45040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj not necessarily dead). 45050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If a Put which is identical, stop with success. 45060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If a Put which might overlap, but is not identical, give up. 45070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If a dirty helper call which might write guest state, give up. 45080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj * If a Put which definitely doesn't overlap, or any other 45090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj kind of stmt, continue. 45100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 45110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj delete = False; 45120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = i+1; j < bb->stmts_used; j++) { 45130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj stj = bb->stmts[j]; 45148bee6d15808653a71717c256a3abe96993439d25sewardj if (stj->tag == Ist_NoOp) 45150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 45160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (identicalPutIs(st, stj)) { 45170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* success! */ 45180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj delete = True; 45190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4520575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 45210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (stj->tag == Ist_Exit) 45220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* give up */ 45230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag == Ist_Dirty) 45250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* give up; could do better here */ 45260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (guestAccessWhichMightOverlapPutI(bb->tyenv, st, stj)) 45280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* give up */ 45290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 45310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 45320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (delete) { 4533575670caec4ae3cb4f3b9395fc9a9837b12432besewardj if (DEBUG_IROPT) { 45340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("rPI: "); 45350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ppIRStmt(st); 4536575670caec4ae3cb4f3b9395fc9a9837b12432besewardj vex_printf("\n"); 4537575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 4538d2445f60726580b450eca68ab40c568f9df338e2sewardj bb->stmts[i] = IRStmt_NoOp(); 45390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4540c819ec16063dab2ec6687da273e58808a3f00a20sewardj 45410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 45420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 4543575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4544575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 45450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 45460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- Loop unrolling ---*/ 45470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 4548575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 45490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Adjust all tmp values (names) in e by delta. e is destructively 45500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj modified. */ 4551575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 45520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void deltaIRExpr ( IRExpr* e, Int delta ) 45530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 45540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 45550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (e->tag) { 4556dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 4557dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e->Iex.RdTmp.tmp += delta; 45580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 45600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Const: 45610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 45630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(e->Iex.GetI.ix, delta); 45640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45651a866b465f5c92df796a5867cd65ac6dec31450bsewardj case Iex_Qop: 456696d7cc3e7d54ad5af2af2821223b21f9a8516a59florian deltaIRExpr(e->Iex.Qop.details->arg1, delta); 456796d7cc3e7d54ad5af2af2821223b21f9a8516a59florian deltaIRExpr(e->Iex.Qop.details->arg2, delta); 456896d7cc3e7d54ad5af2af2821223b21f9a8516a59florian deltaIRExpr(e->Iex.Qop.details->arg3, delta); 456996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian deltaIRExpr(e->Iex.Qop.details->arg4, delta); 45701a866b465f5c92df796a5867cd65ac6dec31450bsewardj break; 4571b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Iex_Triop: 4572420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian deltaIRExpr(e->Iex.Triop.details->arg1, delta); 4573420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian deltaIRExpr(e->Iex.Triop.details->arg2, delta); 4574420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian deltaIRExpr(e->Iex.Triop.details->arg3, delta); 4575b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj break; 45760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Binop: 45770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(e->Iex.Binop.arg1, delta); 45780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(e->Iex.Binop.arg2, delta); 45790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Unop: 45810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(e->Iex.Unop.arg, delta); 45820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4583af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 4584af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj deltaIRExpr(e->Iex.Load.addr, delta); 45850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_CCall: 45870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; e->Iex.CCall.args[i]; i++) 45880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(e->Iex.CCall.args[i], delta); 45890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 459099dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 459199dd03e04a6914d90d5fee727d61d76905334becflorian deltaIRExpr(e->Iex.ITE.cond, delta); 459299dd03e04a6914d90d5fee727d61d76905334becflorian deltaIRExpr(e->Iex.ITE.iftrue, delta); 459399dd03e04a6914d90d5fee727d61d76905334becflorian deltaIRExpr(e->Iex.ITE.iffalse, delta); 45940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 45950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 45960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 45970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("deltaIRExpr"); 45980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 45990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 4600575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Adjust all tmp values (names) in st by delta. st is destructively 46020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj modified. */ 4603575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjstatic void deltaIRStmt ( IRStmt* st, Int delta ) 46050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 46060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 46070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRDirty* d; 46080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 4609d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 4610f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 4611c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 4612f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj break; 46135a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 46145a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj deltaIRExpr(st->Ist.AbiHint.base, delta); 4615478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj deltaIRExpr(st->Ist.AbiHint.nia, delta); 46165a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj break; 46170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 46180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(st->Ist.Put.data, delta); 46190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 46200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_PutI: 4621d6f38b3f822f7d57adfc0da3410995d85d6a4597florian deltaIRExpr(st->Ist.PutI.details->ix, delta); 4622d6f38b3f822f7d57adfc0da3410995d85d6a4597florian deltaIRExpr(st->Ist.PutI.details->data, delta); 46230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4624dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 4625dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj st->Ist.WrTmp.tmp += delta; 4626dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj deltaIRExpr(st->Ist.WrTmp.data, delta); 46270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 46280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Exit: 46290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(st->Ist.Exit.guard, delta); 46300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4631af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 4632af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj deltaIRExpr(st->Ist.Store.addr, delta); 4633af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj deltaIRExpr(st->Ist.Store.data, delta); 46340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4635cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 4636cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 4637cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(sg->addr, delta); 4638cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(sg->data, delta); 4639cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(sg->guard, delta); 4640cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 4641cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 4642cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 4643cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 4644cfe046e178666280b87da998b1b52ecda03ecd89sewardj lg->dst += delta; 4645cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(lg->addr, delta); 4646cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(lg->alt, delta); 4647cfe046e178666280b87da998b1b52ecda03ecd89sewardj deltaIRExpr(lg->guard, delta); 4648cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 4649cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 4650e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 4651e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (st->Ist.CAS.details->oldHi != IRTemp_INVALID) 4652e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj st->Ist.CAS.details->oldHi += delta; 4653e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj st->Ist.CAS.details->oldLo += delta; 4654e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj deltaIRExpr(st->Ist.CAS.details->addr, delta); 4655e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (st->Ist.CAS.details->expdHi) 4656e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj deltaIRExpr(st->Ist.CAS.details->expdHi, delta); 4657e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj deltaIRExpr(st->Ist.CAS.details->expdLo, delta); 4658e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (st->Ist.CAS.details->dataHi) 4659e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj deltaIRExpr(st->Ist.CAS.details->dataHi, delta); 4660e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj deltaIRExpr(st->Ist.CAS.details->dataLo, delta); 4661e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 4662e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 4663e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.result += delta; 4664e768e92e054cde495849a5c842a477d287677f78sewardj deltaIRExpr(st->Ist.LLSC.addr, delta); 4665e768e92e054cde495849a5c842a477d287677f78sewardj if (st->Ist.LLSC.storedata) 4666e768e92e054cde495849a5c842a477d287677f78sewardj deltaIRExpr(st->Ist.LLSC.storedata, delta); 4667e768e92e054cde495849a5c842a477d287677f78sewardj break; 46680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: 46690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d = st->Ist.Dirty.details; 46700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(d->guard, delta); 46712accb5e847cb35149c673e0eefc21baaa723a967florian for (i = 0; d->args[i]; i++) { 46722accb5e847cb35149c673e0eefc21baaa723a967florian IRExpr* arg = d->args[i]; 4673ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 46742accb5e847cb35149c673e0eefc21baaa723a967florian deltaIRExpr(arg, delta); 46752accb5e847cb35149c673e0eefc21baaa723a967florian } 46760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d->tmp != IRTemp_INVALID) 46770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d->tmp += delta; 46780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d->mAddr) 46790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRExpr(d->mAddr, delta); 46800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 46810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 46820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 46830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vpanic("deltaIRStmt"); 46840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 46850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 4686575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4687575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* If possible, return a loop-unrolled version of bb0. The original 46890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj is changed. If not possible, return NULL. */ 4690575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* The two schemas considered are: 4692575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj X: BODY; goto X 4694575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj which unrolls to (eg) X: BODY;BODY; goto X 4696575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj and 4698575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 46990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj X: BODY; if (c) goto X; goto Y 47000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj which trivially transforms to 47010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj X: BODY; if (!c) goto Y; goto X; 47020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj so it falls in the scope of the first case. 4703575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj X and Y must be literal (guest) addresses. 47050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 4706575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4707dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjstatic Int calc_unroll_factor( IRSB* bb ) 4708575670caec4ae3cb4f3b9395fc9a9837b12432besewardj{ 47090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int n_stmts, i; 4710575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj n_stmts = 0; 47120ddbf79767d1dbfad1465e7871247e046536a135sewardj for (i = 0; i < bb->stmts_used; i++) { 47130ddbf79767d1dbfad1465e7871247e046536a135sewardj if (bb->stmts[i]->tag != Ist_NoOp) 47140ddbf79767d1dbfad1465e7871247e046536a135sewardj n_stmts++; 47150ddbf79767d1dbfad1465e7871247e046536a135sewardj } 4716575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (n_stmts <= vex_control.iropt_unroll_thresh/8) { 47180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_verbosity > 0) 47190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("vex iropt: 8 x unrolling (%d sts -> %d sts)\n", 47200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj n_stmts, 8* n_stmts); 47210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return 8; 47220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 47230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (n_stmts <= vex_control.iropt_unroll_thresh/4) { 47240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_verbosity > 0) 47250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("vex iropt: 4 x unrolling (%d sts -> %d sts)\n", 47260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj n_stmts, 4* n_stmts); 47270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return 4; 47280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4729575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47300821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (n_stmts <= vex_control.iropt_unroll_thresh/2) { 47310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_verbosity > 0) 47320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("vex iropt: 2 x unrolling (%d sts -> %d sts)\n", 47330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj n_stmts, 2* n_stmts); 47340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return 2; 4735575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 4736575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_verbosity > 0) 47380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("vex iropt: not unrolling (%d sts)\n", n_stmts); 4739575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 47400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return 1; 4741575670caec4ae3cb4f3b9395fc9a9837b12432besewardj} 4742575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4743575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 4744d4cc0deec55ec0be1f2ac3b20f0d340265341f83florianstatic IRSB* maybe_loop_unroll_BB ( IRSB* bb0, Addr my_addr ) 4745e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj{ 47460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i, j, jmax, n_vars; 47470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Bool xxx_known; 47480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Addr64 xxx_value, yyy_value; 47490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* udst; 47500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 47510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRConst* con; 4752dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB *bb1, *bb2; 47530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int unroll_factor; 47543e2ba0ab79fdd03585492b1434a04b0eb34894bfsewardj 47550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_unroll_thresh <= 0) 47560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 47570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 47580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* First off, figure out if we can unroll this loop. Do this 47590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj without modifying bb0. */ 47600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 47610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (bb0->jumpkind != Ijk_Boring) 47620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 47630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 47640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj xxx_known = False; 47650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj xxx_value = 0; 47660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 47670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Extract the next-guest address. If it isn't a literal, we 47680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj have to give up. */ 47690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 47700821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst = bb0->next; 47710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (udst->tag == Iex_Const 47720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj && (udst->Iex.Const.con->tag == Ico_U32 47730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj || udst->Iex.Const.con->tag == Ico_U64)) { 47740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* The BB ends in a jump to a literal location. */ 47750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj xxx_known = True; 47760821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj xxx_value = udst->Iex.Const.con->tag == Ico_U64 47770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? udst->Iex.Const.con->Ico.U64 47780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj : (Addr64)(udst->Iex.Const.con->Ico.U32); 47793e2ba0ab79fdd03585492b1434a04b0eb34894bfsewardj } 47803e2ba0ab79fdd03585492b1434a04b0eb34894bfsewardj 47810821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (!xxx_known) 47820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 4783e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 47840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Now we know the BB ends to a jump to a literal location. If 47850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj it's a jump to itself (viz, idiom #1), move directly to the 47860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj unrolling stage, first cloning the bb so the original isn't 47870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj modified. */ 47880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (xxx_value == my_addr) { 47890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj unroll_factor = calc_unroll_factor( bb0 ); 47900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (unroll_factor < 2) 47910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 4792dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb1 = deepCopyIRSB( bb0 ); 47930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb0 = NULL; 47940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst = NULL; /* is now invalid */ 47950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj goto do_unroll; 47960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4797e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 47980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Search for the second idiomatic form: 47990821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj X: BODY; if (c) goto X; goto Y 48000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj We know Y, but need to establish that the last stmt 48010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj is 'if (c) goto X'. 48020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 48030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj yyy_value = xxx_value; 48040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb0->stmts_used-1; i >= 0; i--) 48050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (bb0->stmts[i]) 48060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 48070ec972d3d99377267d6ba990045f6db970363047sewardj 48080821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (i < 0) 48090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; /* block with no stmts. Strange. */ 48100ec972d3d99377267d6ba990045f6db970363047sewardj 48110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb0->stmts[i]; 48120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->tag != Ist_Exit) 48130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 48140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (st->Ist.Exit.jk != Ijk_Boring) 48150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 4816e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con = st->Ist.Exit.dst; 48180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(con->tag == Ico_U32 || con->tag == Ico_U64); 48190ec972d3d99377267d6ba990045f6db970363047sewardj 48200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj xxx_value = con->tag == Ico_U64 48210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ? st->Ist.Exit.dst->Ico.U64 48220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj : (Addr64)(st->Ist.Exit.dst->Ico.U32); 48230ec972d3d99377267d6ba990045f6db970363047sewardj 48240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* If this assertion fails, we have some kind of type error. */ 48250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(con->tag == udst->Iex.Const.con->tag); 4826e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (xxx_value != my_addr) 48280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* We didn't find either idiom. Give up. */ 48290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 4830e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Ok, we found idiom #2. Copy the BB, switch around the xxx and 48320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj yyy values (which makes it look like idiom #1), and go into 48330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj unrolling proper. This means finding (again) the last stmt, in 48340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj the copied BB. */ 48350ec972d3d99377267d6ba990045f6db970363047sewardj 48360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj unroll_factor = calc_unroll_factor( bb0 ); 48370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (unroll_factor < 2) 48380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return NULL; 4839e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 4840dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb1 = deepCopyIRSB( bb0 ); 48410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb0 = NULL; 48420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst = NULL; /* is now invalid */ 48430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = bb1->stmts_used-1; i >= 0; i--) 48440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (bb1->stmts[i]) 48450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj break; 4846eb30964230574023e99952904bb108625b6403e7sewardj 48470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* The next bunch of assertions should be true since we already 48480821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj found and checked the last stmt in the original bb. */ 4849e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(i >= 0); 4851e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb1->stmts[i]; 48530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(st->tag == Ist_Exit); 4854e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 48550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con = st->Ist.Exit.dst; 48560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(con->tag == Ico_U32 || con->tag == Ico_U64); 4857a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48580821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst = bb1->next; 48590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(udst->tag == Iex_Const); 48600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(udst->Iex.Const.con->tag == Ico_U32 48610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj || udst->Iex.Const.con->tag == Ico_U64); 48620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(con->tag == udst->Iex.Const.con->tag); 4863575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 48640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* switch the xxx and yyy fields around */ 48650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (con->tag == Ico_U64) { 48660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst->Iex.Const.con->Ico.U64 = xxx_value; 48670821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj con->Ico.U64 = yyy_value; 48680821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } else { 48690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj udst->Iex.Const.con->Ico.U32 = (UInt)xxx_value; 487057b4c6dadda048b86f99d286c4ddbefc69cfe670cerion con->Ico.U32 = (UInt)yyy_value; 48710821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4872a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* negate the test condition */ 48740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st->Ist.Exit.guard 4875dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj = IRExpr_Unop(Iop_Not1,deepCopyIRExpr(st->Ist.Exit.guard)); 4876a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* --- The unroller proper. Both idioms are by now --- */ 48780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* --- now converted to idiom 1. --- */ 4879a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj do_unroll: 4881a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(unroll_factor == 2 48830821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj || unroll_factor == 4 48840821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj || unroll_factor == 8); 4885a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj jmax = unroll_factor==8 ? 3 : (unroll_factor==4 ? 2 : 1); 48870821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (j = 1; j <= jmax; j++) { 4888a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj n_vars = bb1->tyenv->types_used; 4890ae27ab65d3bb9cc82520ebd3454a6bee3e95e21asewardj 4891dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb2 = deepCopyIRSB(bb1); 48920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < n_vars; i++) 48930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (void)newIRTemp(bb1->tyenv, bb2->tyenv->types[i]); 4894a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 48950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb2->stmts_used; i++) { 48960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* deltaIRStmt destructively modifies the stmt, but 48970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj that's OK since bb2 is a complete fresh copy of bb1. */ 48980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj deltaIRStmt(bb2->stmts[i], n_vars); 4899dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addStmtToIRSB(bb1, bb2->stmts[i]); 49000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 49010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4902575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 49030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (DEBUG_IROPT) { 4904d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian vex_printf("\nUNROLLED (%lx)\n", my_addr); 4905dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb1); 49060821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); 49070821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 4908a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 49090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Flattening; sigh. The unroller succeeds in breaking flatness 49100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj by negating the test condition. This should be fixed properly. 49110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj For the moment use this shotgun approach. */ 49120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return flatten_BB(bb1); 49130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 4914a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 49150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 49160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 49170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*--- The tree builder ---*/ 49180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/*---------------------------------------------------------------*/ 49190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 49200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* This isn't part of IR optimisation. Really it's a pass done prior 49210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj to instruction selection, which improves the code that the 49220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj instruction selector can produce. */ 49230821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 4924f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* --- The 'tmp' environment is the central data structure here --- */ 4925f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 4926f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* The number of outstanding bindings we're prepared to track. 4927f9517d0d452899780e8c34f02bef004ef7c5a163sewardj The number of times the env becomes full and we have to dump 4928f9517d0d452899780e8c34f02bef004ef7c5a163sewardj the oldest binding (hence reducing code quality) falls very 4929f9517d0d452899780e8c34f02bef004ef7c5a163sewardj rapidly as the env size increases. 8 gives reasonable performance 4930f9517d0d452899780e8c34f02bef004ef7c5a163sewardj under most circumstances. */ 4931f9517d0d452899780e8c34f02bef004ef7c5a163sewardj#define A_NENV 10 4932f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 4933740da72e3938e8474234420777c17c1a4be6cb6fflorian/* An interval. Used to record the bytes in the guest state accessed 4934740da72e3938e8474234420777c17c1a4be6cb6fflorian by a Put[I] statement or by (one or more) Get[I] expression(s). In 4935740da72e3938e8474234420777c17c1a4be6cb6fflorian case of several Get[I] expressions, the lower/upper bounds are recorded. 4936740da72e3938e8474234420777c17c1a4be6cb6fflorian This is conservative but cheap. 4937740da72e3938e8474234420777c17c1a4be6cb6fflorian E.g. a Put of 8 bytes at address 100 would be recorded as [100,107]. 4938740da72e3938e8474234420777c17c1a4be6cb6fflorian E.g. an expression that reads 8 bytes at offset 100 and 4 bytes at 4939740da72e3938e8474234420777c17c1a4be6cb6fflorian offset 200 would be recorded as [100,203] */ 4940740da72e3938e8474234420777c17c1a4be6cb6ffloriantypedef 4941740da72e3938e8474234420777c17c1a4be6cb6fflorian struct { 4942740da72e3938e8474234420777c17c1a4be6cb6fflorian Bool present; 4943740da72e3938e8474234420777c17c1a4be6cb6fflorian Int low; 4944740da72e3938e8474234420777c17c1a4be6cb6fflorian Int high; 4945740da72e3938e8474234420777c17c1a4be6cb6fflorian } 4946740da72e3938e8474234420777c17c1a4be6cb6fflorian Interval; 4947740da72e3938e8474234420777c17c1a4be6cb6fflorian 4948740da72e3938e8474234420777c17c1a4be6cb6fflorianstatic inline Bool 4949740da72e3938e8474234420777c17c1a4be6cb6fflorianintervals_overlap(Interval i1, Interval i2) 4950740da72e3938e8474234420777c17c1a4be6cb6fflorian{ 4951740da72e3938e8474234420777c17c1a4be6cb6fflorian return (i1.low >= i2.low && i1.low <= i2.high) || 4952740da72e3938e8474234420777c17c1a4be6cb6fflorian (i2.low >= i1.low && i2.low <= i1.high); 4953740da72e3938e8474234420777c17c1a4be6cb6fflorian} 4954740da72e3938e8474234420777c17c1a4be6cb6fflorian 4955740da72e3938e8474234420777c17c1a4be6cb6fflorianstatic inline void 4956740da72e3938e8474234420777c17c1a4be6cb6fflorianupdate_interval(Interval *i, Int low, Int high) 4957740da72e3938e8474234420777c17c1a4be6cb6fflorian{ 4958740da72e3938e8474234420777c17c1a4be6cb6fflorian vassert(low <= high); 4959740da72e3938e8474234420777c17c1a4be6cb6fflorian 4960740da72e3938e8474234420777c17c1a4be6cb6fflorian if (i->present) { 4961740da72e3938e8474234420777c17c1a4be6cb6fflorian if (low < i->low) i->low = low; 4962740da72e3938e8474234420777c17c1a4be6cb6fflorian if (high > i->high) i->high = high; 4963740da72e3938e8474234420777c17c1a4be6cb6fflorian } else { 4964740da72e3938e8474234420777c17c1a4be6cb6fflorian i->present = True; 4965740da72e3938e8474234420777c17c1a4be6cb6fflorian i->low = low; 4966740da72e3938e8474234420777c17c1a4be6cb6fflorian i->high = high; 4967740da72e3938e8474234420777c17c1a4be6cb6fflorian } 4968740da72e3938e8474234420777c17c1a4be6cb6fflorian} 4969740da72e3938e8474234420777c17c1a4be6cb6fflorian 4970740da72e3938e8474234420777c17c1a4be6cb6fflorian 4971f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* bindee == NULL === slot is not in use 4972f9517d0d452899780e8c34f02bef004ef7c5a163sewardj bindee != NULL === slot is in use 4973f9517d0d452899780e8c34f02bef004ef7c5a163sewardj*/ 49740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardjtypedef 4975f9517d0d452899780e8c34f02bef004ef7c5a163sewardj struct { 4976f9517d0d452899780e8c34f02bef004ef7c5a163sewardj IRTemp binder; 4977f9517d0d452899780e8c34f02bef004ef7c5a163sewardj IRExpr* bindee; 4978f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Bool doesLoad; 4979740da72e3938e8474234420777c17c1a4be6cb6fflorian /* Record the bytes of the guest state BINDEE reads from. */ 4980740da72e3938e8474234420777c17c1a4be6cb6fflorian Interval getInterval; 4981575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 4982f9517d0d452899780e8c34f02bef004ef7c5a163sewardj ATmpInfo; 4983a5dc3486e32efe9a5fc28f23addbdd1a857f0ab0sewardj 4984f9517d0d452899780e8c34f02bef004ef7c5a163sewardj__attribute__((unused)) 4985f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic void ppAEnv ( ATmpInfo* env ) 4986f9517d0d452899780e8c34f02bef004ef7c5a163sewardj{ 4987f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Int i; 4988f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; i < A_NENV; i++) { 4989f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vex_printf("%d tmp %d val ", i, (Int)env[i].binder); 4990f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (env[i].bindee) 4991f9517d0d452899780e8c34f02bef004ef7c5a163sewardj ppIRExpr(env[i].bindee); 4992f9517d0d452899780e8c34f02bef004ef7c5a163sewardj else 4993f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vex_printf("(null)"); 4994f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vex_printf("\n"); 4995f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 4996f9517d0d452899780e8c34f02bef004ef7c5a163sewardj} 4997f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 4998f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* --- Tree-traversal fns --- */ 4999f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5000f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* Traverse an expr, and detect if any part of it reads memory or does 5001f9517d0d452899780e8c34f02bef004ef7c5a163sewardj a Get. Be careful ... this really controls how much the 5002f9517d0d452899780e8c34f02bef004ef7c5a163sewardj tree-builder can reorder the code, so getting it right is critical. 50030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 5004740da72e3938e8474234420777c17c1a4be6cb6fflorianstatic void setHints_Expr (Bool* doesLoad, Interval* getInterval, IRExpr* e ) 50050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 5006f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Int i; 5007f9517d0d452899780e8c34f02bef004ef7c5a163sewardj switch (e->tag) { 5008f9517d0d452899780e8c34f02bef004ef7c5a163sewardj case Iex_CCall: 5009f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; e->Iex.CCall.args[i]; i++) 5010740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.CCall.args[i]); 5011f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 501299dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 5013740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.ITE.cond); 5014740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.ITE.iftrue); 5015740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.ITE.iffalse); 5016f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 501740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj case Iex_Qop: 5018740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Qop.details->arg1); 5019740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Qop.details->arg2); 5020740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Qop.details->arg3); 5021740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Qop.details->arg4); 502240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return; 5023b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Iex_Triop: 5024740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Triop.details->arg1); 5025740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Triop.details->arg2); 5026740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Triop.details->arg3); 5027b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return; 5028f9517d0d452899780e8c34f02bef004ef7c5a163sewardj case Iex_Binop: 5029740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Binop.arg1); 5030740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Binop.arg2); 5031f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5032f9517d0d452899780e8c34f02bef004ef7c5a163sewardj case Iex_Unop: 5033740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Unop.arg); 5034f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5035f9517d0d452899780e8c34f02bef004ef7c5a163sewardj case Iex_Load: 5036f9517d0d452899780e8c34f02bef004ef7c5a163sewardj *doesLoad = True; 5037740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.Load.addr); 5038f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5039740da72e3938e8474234420777c17c1a4be6cb6fflorian case Iex_Get: { 5040740da72e3938e8474234420777c17c1a4be6cb6fflorian Int low = e->Iex.Get.offset; 5041740da72e3938e8474234420777c17c1a4be6cb6fflorian Int high = low + sizeofIRType(e->Iex.Get.ty) - 1; 5042740da72e3938e8474234420777c17c1a4be6cb6fflorian update_interval(getInterval, low, high); 5043f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5044740da72e3938e8474234420777c17c1a4be6cb6fflorian } 5045740da72e3938e8474234420777c17c1a4be6cb6fflorian case Iex_GetI: { 5046740da72e3938e8474234420777c17c1a4be6cb6fflorian IRRegArray *descr = e->Iex.GetI.descr; 5047740da72e3938e8474234420777c17c1a4be6cb6fflorian Int size = sizeofIRType(descr->elemTy); 5048740da72e3938e8474234420777c17c1a4be6cb6fflorian Int low = descr->base; 5049740da72e3938e8474234420777c17c1a4be6cb6fflorian Int high = low + descr->nElems * size - 1; 5050740da72e3938e8474234420777c17c1a4be6cb6fflorian update_interval(getInterval, low, high); 5051740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(doesLoad, getInterval, e->Iex.GetI.ix); 5052f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5053740da72e3938e8474234420777c17c1a4be6cb6fflorian } 5054dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 5055f9517d0d452899780e8c34f02bef004ef7c5a163sewardj case Iex_Const: 5056f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return; 5057f9517d0d452899780e8c34f02bef004ef7c5a163sewardj default: 5058f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 5059f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vpanic("setHints_Expr"); 50600821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 5061575670caec4ae3cb4f3b9395fc9a9837b12432besewardj} 5062575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 5063f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5064f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* Add a binding to the front of the env and slide all the rest 5065f9517d0d452899780e8c34f02bef004ef7c5a163sewardj backwards. It should be the case that the last slot is free. */ 5066f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic void addToEnvFront ( ATmpInfo* env, IRTemp binder, IRExpr* bindee ) 5067f9517d0d452899780e8c34f02bef004ef7c5a163sewardj{ 5068f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Int i; 5069f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vassert(env[A_NENV-1].bindee == NULL); 5070f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = A_NENV-1; i >= 1; i--) 5071f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[i] = env[i-1]; 5072f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[0].binder = binder; 5073f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[0].bindee = bindee; 5074f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[0].doesLoad = False; /* filled in later */ 5075740da72e3938e8474234420777c17c1a4be6cb6fflorian env[0].getInterval.present = False; /* filled in later */ 5076740da72e3938e8474234420777c17c1a4be6cb6fflorian env[0].getInterval.low = -1; /* filled in later */ 5077740da72e3938e8474234420777c17c1a4be6cb6fflorian env[0].getInterval.high = -1; /* filled in later */ 5078f9517d0d452899780e8c34f02bef004ef7c5a163sewardj} 5079f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5080f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* Given uses :: array of UShort, indexed by IRTemp 5081f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Add the use-occurrences of temps in this expression 5082f9517d0d452899780e8c34f02bef004ef7c5a163sewardj to the env. 5083f9517d0d452899780e8c34f02bef004ef7c5a163sewardj*/ 5084f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic void aoccCount_Expr ( UShort* uses, IRExpr* e ) 50850821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 50860821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 5087575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 50880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (e->tag) { 5089575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 5090dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: /* the only interesting case */ 5091dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj uses[e->Iex.RdTmp.tmp]++; 50920821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5093728c9d59db14f528e3d47a5c2bf2027407ea133esewardj 509499dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 509599dd03e04a6914d90d5fee727d61d76905334becflorian aoccCount_Expr(uses, e->Iex.ITE.cond); 509699dd03e04a6914d90d5fee727d61d76905334becflorian aoccCount_Expr(uses, e->Iex.ITE.iftrue); 509799dd03e04a6914d90d5fee727d61d76905334becflorian aoccCount_Expr(uses, e->Iex.ITE.iffalse); 50980821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5099575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 510040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj case Iex_Qop: 510196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian aoccCount_Expr(uses, e->Iex.Qop.details->arg1); 510296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian aoccCount_Expr(uses, e->Iex.Qop.details->arg2); 510396d7cc3e7d54ad5af2af2821223b21f9a8516a59florian aoccCount_Expr(uses, e->Iex.Qop.details->arg3); 510496d7cc3e7d54ad5af2af2821223b21f9a8516a59florian aoccCount_Expr(uses, e->Iex.Qop.details->arg4); 510540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return; 510640c802659108a96bb87cbc1a30b7b77e2abd0829sewardj 5107b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Iex_Triop: 5108420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian aoccCount_Expr(uses, e->Iex.Triop.details->arg1); 5109420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian aoccCount_Expr(uses, e->Iex.Triop.details->arg2); 5110420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian aoccCount_Expr(uses, e->Iex.Triop.details->arg3); 5111b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return; 5112b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 51130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Binop: 5114f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.Binop.arg1); 5115f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.Binop.arg2); 51160821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5117e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 51180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Unop: 5119f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.Unop.arg); 51200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5121e98dcf23f5f6c301ddbfebd77f246accfa61f4ccsewardj 5122af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 5123f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.Load.addr); 51240821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5125575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 51260821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_CCall: 51270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; e->Iex.CCall.args[i]; i++) 5128f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.CCall.args[i]); 51290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5130575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 51310821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 5132f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, e->Iex.GetI.ix); 51330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5134575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 51350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Const: 51360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 51370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5138575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 51390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 51400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 5141f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vpanic("aoccCount_Expr"); 51420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 51430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 5144575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 5145575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 5146f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* Given uses :: array of UShort, indexed by IRTemp 5147f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Add the use-occurrences of temps in this statement 5148f9517d0d452899780e8c34f02bef004ef7c5a163sewardj to the env. 51490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj*/ 5150f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic void aoccCount_Stmt ( UShort* uses, IRStmt* st ) 51510821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 51520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 51530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRDirty* d; 5154e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRCAS* cas; 51550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj switch (st->tag) { 51565a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 5157f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, st->Ist.AbiHint.base); 5158478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj aoccCount_Expr(uses, st->Ist.AbiHint.nia); 51595a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj return; 5160dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 5161dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj aoccCount_Expr(uses, st->Ist.WrTmp.data); 51620821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 51630821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Put: 5164f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, st->Ist.Put.data); 51650821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 51660821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_PutI: 5167d6f38b3f822f7d57adfc0da3410995d85d6a4597florian aoccCount_Expr(uses, st->Ist.PutI.details->ix); 5168d6f38b3f822f7d57adfc0da3410995d85d6a4597florian aoccCount_Expr(uses, st->Ist.PutI.details->data); 51690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5170af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 5171f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, st->Ist.Store.addr); 5172f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, st->Ist.Store.data); 51730821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5174cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 5175cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 5176cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, sg->addr); 5177cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, sg->data); 5178cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, sg->guard); 5179cfe046e178666280b87da998b1b52ecda03ecd89sewardj return; 5180cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 5181cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 5182cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 5183cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, lg->addr); 5184cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, lg->alt); 5185cfe046e178666280b87da998b1b52ecda03ecd89sewardj aoccCount_Expr(uses, lg->guard); 5186cfe046e178666280b87da998b1b52ecda03ecd89sewardj return; 5187cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 5188e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 5189e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 5190e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aoccCount_Expr(uses, cas->addr); 5191e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (cas->expdHi) 5192e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aoccCount_Expr(uses, cas->expdHi); 5193e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aoccCount_Expr(uses, cas->expdLo); 5194e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj if (cas->dataHi) 5195e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aoccCount_Expr(uses, cas->dataHi); 5196e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj aoccCount_Expr(uses, cas->dataLo); 5197e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return; 5198e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 5199e768e92e054cde495849a5c842a477d287677f78sewardj aoccCount_Expr(uses, st->Ist.LLSC.addr); 5200e768e92e054cde495849a5c842a477d287677f78sewardj if (st->Ist.LLSC.storedata) 5201e768e92e054cde495849a5c842a477d287677f78sewardj aoccCount_Expr(uses, st->Ist.LLSC.storedata); 5202e768e92e054cde495849a5c842a477d287677f78sewardj return; 52030821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Dirty: 52040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d = st->Ist.Dirty.details; 52050821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d->mFx != Ifx_None) 5206f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, d->mAddr); 5207f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, d->guard); 520874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (i = 0; d->args[i]; i++) { 520974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d->args[i]; 5210ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 521174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj aoccCount_Expr(uses, arg); 521274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 52130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 5214d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 5215f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 5216c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 52173e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj return; 52180821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Ist_Exit: 5219f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, st->Ist.Exit.guard); 52200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return; 52210821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj default: 52220821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 5223f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vpanic("aoccCount_Stmt"); 5224575670caec4ae3cb4f3b9395fc9a9837b12432besewardj } 5225728c9d59db14f528e3d47a5c2bf2027407ea133esewardj} 52264345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 52270821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Look up a binding for tmp in the env. If found, return the bound 52280821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj expression, and set the env's binding to NULL so it is marked as 52290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj used. If not found, return NULL. */ 5230575670caec4ae3cb4f3b9395fc9a9837b12432besewardj 5231f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic IRExpr* atbSubst_Temp ( ATmpInfo* env, IRTemp tmp ) 52320821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 5233f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Int i; 5234f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; i < A_NENV; i++) { 5235f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (env[i].binder == tmp && env[i].bindee != NULL) { 5236f9517d0d452899780e8c34f02bef004ef7c5a163sewardj IRExpr* bindee = env[i].bindee; 5237f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[i].bindee = NULL; 5238f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return bindee; 52390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 52400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 5241f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return NULL; 52420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj} 5243edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj 52440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj/* Traverse e, looking for temps. For each observed temp, see if env 52450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj contains a binding for the temp, and if so return the bound value. 52460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj The env has the property that any binding it holds is 52470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 'single-shot', so once a binding is used, it is marked as no longer 5248f9517d0d452899780e8c34f02bef004ef7c5a163sewardj available, by setting its .bindee field to NULL. */ 5249f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 5250eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardjstatic inline Bool is_Unop ( IRExpr* e, IROp op ) { 5251eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return e->tag == Iex_Unop && e->Iex.Unop.op == op; 5252eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj} 5253eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardjstatic inline Bool is_Binop ( IRExpr* e, IROp op ) { 5254eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return e->tag == Iex_Binop && e->Iex.Binop.op == op; 5255eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj} 5256eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 5257eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardjstatic IRExpr* fold_IRExpr_Binop ( IROp op, IRExpr* a1, IRExpr* a2 ) 5258eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj{ 5259eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj switch (op) { 5260eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_Or32: 5261eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* Or32( CmpwNEZ32(x), CmpwNEZ32(y) ) --> CmpwNEZ32( Or32( x, y ) ) */ 5262eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(a1, Iop_CmpwNEZ32) && is_Unop(a2, Iop_CmpwNEZ32)) 5263eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( Iop_CmpwNEZ32, 5264eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj IRExpr_Binop( Iop_Or32, a1->Iex.Unop.arg, 5265eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj a2->Iex.Unop.arg ) ); 5266eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 526751d26fd8c2df9a0d0844ba9198be9152d18dab04florian 526851d26fd8c2df9a0d0844ba9198be9152d18dab04florian case Iop_CmpNE32: 526951d26fd8c2df9a0d0844ba9198be9152d18dab04florian /* Since X has type Ity_I1 we can simplify: 527051d26fd8c2df9a0d0844ba9198be9152d18dab04florian CmpNE32(1Uto32(X),0)) ==> X */ 527151d26fd8c2df9a0d0844ba9198be9152d18dab04florian if (is_Unop(a1, Iop_1Uto32) && isZeroU32(a2)) 527251d26fd8c2df9a0d0844ba9198be9152d18dab04florian return a1->Iex.Unop.arg; 527351d26fd8c2df9a0d0844ba9198be9152d18dab04florian break; 527451d26fd8c2df9a0d0844ba9198be9152d18dab04florian 5275eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj default: 5276eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5277eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 5278eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* no reduction rule applies */ 5279eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Binop( op, a1, a2 ); 5280eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj} 5281eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 5282eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardjstatic IRExpr* fold_IRExpr_Unop ( IROp op, IRExpr* aa ) 5283eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj{ 5284eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj switch (op) { 5285eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpwNEZ64: 5286de6f7105b663609e3ff0137726522b3bae135195florian /* CmpwNEZ64( CmpwNEZ64 ( x ) ) --> CmpwNEZ64 ( x ) */ 5287de6f7105b663609e3ff0137726522b3bae135195florian if (is_Unop(aa, Iop_CmpwNEZ64)) 5288de6f7105b663609e3ff0137726522b3bae135195florian return IRExpr_Unop( Iop_CmpwNEZ64, aa->Iex.Unop.arg ); 5289eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* CmpwNEZ64( Or64 ( CmpwNEZ64(x), y ) ) --> CmpwNEZ64( Or64( x, y ) ) */ 5290eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Binop(aa, Iop_Or64) 5291eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj && is_Unop(aa->Iex.Binop.arg1, Iop_CmpwNEZ64)) 5292eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return fold_IRExpr_Unop( 5293eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj Iop_CmpwNEZ64, 5294eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj IRExpr_Binop(Iop_Or64, 5295eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj aa->Iex.Binop.arg1->Iex.Unop.arg, 5296eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj aa->Iex.Binop.arg2)); 5297eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* CmpwNEZ64( Or64 ( x, CmpwNEZ64(y) ) ) --> CmpwNEZ64( Or64( x, y ) ) */ 5298eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Binop(aa, Iop_Or64) 5299eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj && is_Unop(aa->Iex.Binop.arg2, Iop_CmpwNEZ64)) 5300eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return fold_IRExpr_Unop( 5301eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj Iop_CmpwNEZ64, 5302eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj IRExpr_Binop(Iop_Or64, 5303eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj aa->Iex.Binop.arg1, 5304eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj aa->Iex.Binop.arg2->Iex.Unop.arg)); 5305eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5306eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpNEZ64: 5307eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* CmpNEZ64( Left64(x) ) --> CmpNEZ64(x) */ 5308eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_Left64)) 5309eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop(Iop_CmpNEZ64, aa->Iex.Unop.arg); 5310de6f7105b663609e3ff0137726522b3bae135195florian /* CmpNEZ64( 1Uto64(X) ) --> X */ 5311de6f7105b663609e3ff0137726522b3bae135195florian if (is_Unop(aa, Iop_1Uto64)) 5312de6f7105b663609e3ff0137726522b3bae135195florian return aa->Iex.Unop.arg; 5313eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5314eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpwNEZ32: 5315eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* CmpwNEZ32( CmpwNEZ32 ( x ) ) --> CmpwNEZ32 ( x ) */ 5316eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_CmpwNEZ32)) 5317eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( Iop_CmpwNEZ32, aa->Iex.Unop.arg ); 5318eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5319eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_CmpNEZ32: 5320eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* CmpNEZ32( Left32(x) ) --> CmpNEZ32(x) */ 5321eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_Left32)) 5322eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop(Iop_CmpNEZ32, aa->Iex.Unop.arg); 532351d26fd8c2df9a0d0844ba9198be9152d18dab04florian /* CmpNEZ32( 1Uto32(X) ) --> X */ 532451d26fd8c2df9a0d0844ba9198be9152d18dab04florian if (is_Unop(aa, Iop_1Uto32)) 532551d26fd8c2df9a0d0844ba9198be9152d18dab04florian return aa->Iex.Unop.arg; 5326de6f7105b663609e3ff0137726522b3bae135195florian /* CmpNEZ32( 64to32( CmpwNEZ64(X) ) ) --> CmpNEZ64(X) */ 5327de6f7105b663609e3ff0137726522b3bae135195florian if (is_Unop(aa, Iop_64to32) && is_Unop(aa->Iex.Unop.arg, Iop_CmpwNEZ64)) 5328de6f7105b663609e3ff0137726522b3bae135195florian return IRExpr_Unop(Iop_CmpNEZ64, aa->Iex.Unop.arg->Iex.Unop.arg); 532951d26fd8c2df9a0d0844ba9198be9152d18dab04florian break; 533051d26fd8c2df9a0d0844ba9198be9152d18dab04florian case Iop_CmpNEZ8: 533151d26fd8c2df9a0d0844ba9198be9152d18dab04florian /* CmpNEZ8( 1Uto8(X) ) --> X */ 533251d26fd8c2df9a0d0844ba9198be9152d18dab04florian if (is_Unop(aa, Iop_1Uto8)) 533351d26fd8c2df9a0d0844ba9198be9152d18dab04florian return aa->Iex.Unop.arg; 5334eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5335eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_Left32: 5336eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* Left32( Left32(x) ) --> Left32(x) */ 5337eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_Left32)) 5338eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( Iop_Left32, aa->Iex.Unop.arg ); 5339eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5340854912aab0e19f3f2dc4c3e2e6ed150871deb846florian case Iop_Left64: 5341854912aab0e19f3f2dc4c3e2e6ed150871deb846florian /* Left64( Left64(x) ) --> Left64(x) */ 5342854912aab0e19f3f2dc4c3e2e6ed150871deb846florian if (is_Unop(aa, Iop_Left64)) 5343854912aab0e19f3f2dc4c3e2e6ed150871deb846florian return IRExpr_Unop( Iop_Left64, aa->Iex.Unop.arg ); 5344854912aab0e19f3f2dc4c3e2e6ed150871deb846florian break; 53450caa0c050206658c1309702e84aa1957e3694c16sewardj case Iop_ZeroHI64ofV128: 53460caa0c050206658c1309702e84aa1957e3694c16sewardj /* ZeroHI64ofV128( ZeroHI64ofV128(x) ) --> ZeroHI64ofV128(x) */ 53470caa0c050206658c1309702e84aa1957e3694c16sewardj if (is_Unop(aa, Iop_ZeroHI64ofV128)) 53480caa0c050206658c1309702e84aa1957e3694c16sewardj return IRExpr_Unop( Iop_ZeroHI64ofV128, aa->Iex.Unop.arg ); 53490caa0c050206658c1309702e84aa1957e3694c16sewardj break; 5350eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_32to1: 5351eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* 32to1( 1Uto32 ( x ) ) --> x */ 5352eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_1Uto32)) 5353eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return aa->Iex.Unop.arg; 5354eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* 32to1( CmpwNEZ32 ( x )) --> CmpNEZ32(x) */ 5355eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_CmpwNEZ32)) 5356eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( Iop_CmpNEZ32, aa->Iex.Unop.arg ); 5357eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5358eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj case Iop_64to1: 5359eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* 64to1( 1Uto64 ( x ) ) --> x */ 5360eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_1Uto64)) 5361eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return aa->Iex.Unop.arg; 5362eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* 64to1( CmpwNEZ64 ( x )) --> CmpNEZ64(x) */ 5363eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj if (is_Unop(aa, Iop_CmpwNEZ64)) 5364eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( Iop_CmpNEZ64, aa->Iex.Unop.arg ); 5365eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5366ef425db9c4d0ceefa2f1b941f29af318d63542efsewardj case Iop_64to32: 5367ef425db9c4d0ceefa2f1b941f29af318d63542efsewardj /* 64to32( 32Uto64 ( x )) --> x */ 5368ef425db9c4d0ceefa2f1b941f29af318d63542efsewardj if (is_Unop(aa, Iop_32Uto64)) 5369ef425db9c4d0ceefa2f1b941f29af318d63542efsewardj return aa->Iex.Unop.arg; 5370ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* 64to32( 8Uto64 ( x )) --> 8Uto32(x) */ 5371ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj if (is_Unop(aa, Iop_8Uto64)) 5372ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj return IRExpr_Unop(Iop_8Uto32, aa->Iex.Unop.arg); 5373ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj break; 5374ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj 5375ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj case Iop_32Uto64: 5376ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* 32Uto64( 8Uto32( x )) --> 8Uto64(x) */ 5377ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj if (is_Unop(aa, Iop_8Uto32)) 5378ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj return IRExpr_Unop(Iop_8Uto64, aa->Iex.Unop.arg); 5379ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj /* 32Uto64( 16Uto32( x )) --> 16Uto64(x) */ 5380ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj if (is_Unop(aa, Iop_16Uto32)) 5381ca257bc572147c1a9c7d9a2e81237125a35ff25dsewardj return IRExpr_Unop(Iop_16Uto64, aa->Iex.Unop.arg); 5382bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj /* 32Uto64(64to32( Shr64( 32Uto64(64to32(x)), sh )) 5383bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj --> Shr64( 32Uto64(64to32(x)), sh )) */ 5384bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj if (is_Unop(aa, Iop_64to32) 5385bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Binop(aa->Iex.Unop.arg, Iop_Shr64) 5386bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1, Iop_32Uto64) 5387bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg, 5388bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj Iop_64to32)) { 5389bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj return aa->Iex.Unop.arg; 5390bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj } 5391bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj /* 32Uto64(64to32( Shl64( 32Uto64(64to32(x)), sh )) 5392bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj --> 32Uto64(64to32( Shl64( x, sh )) */ 5393bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj if (is_Unop(aa, Iop_64to32) 5394bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Binop(aa->Iex.Unop.arg, Iop_Shl64) 5395bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1, Iop_32Uto64) 5396bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj && is_Unop(aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg, 5397bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj Iop_64to32)) { 5398bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj return 5399bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj IRExpr_Unop( 5400bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj Iop_32Uto64, 5401bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj IRExpr_Unop( 5402bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj Iop_64to32, 5403bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj IRExpr_Binop( 5404bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj Iop_Shl64, 5405bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj aa->Iex.Unop.arg->Iex.Binop.arg1->Iex.Unop.arg->Iex.Unop.arg, 5406bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj aa->Iex.Unop.arg->Iex.Binop.arg2 5407bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj ))); 5408bba356d54ba2a6f04f7c60806b5ad6a81f88644asewardj } 5409ef425db9c4d0ceefa2f1b941f29af318d63542efsewardj break; 54106c299f3acab617581ea504e45fbb6cab24c2b29fsewardj 54116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj case Iop_1Sto32: 54126c299f3acab617581ea504e45fbb6cab24c2b29fsewardj /* 1Sto32( CmpNEZ8( 32to8( 1Uto32( CmpNEZ32( x ))))) -> CmpwNEZ32(x) */ 54136c299f3acab617581ea504e45fbb6cab24c2b29fsewardj if (is_Unop(aa, Iop_CmpNEZ8) 54146c299f3acab617581ea504e45fbb6cab24c2b29fsewardj && is_Unop(aa->Iex.Unop.arg, Iop_32to8) 54156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj && is_Unop(aa->Iex.Unop.arg->Iex.Unop.arg, Iop_1Uto32) 54166c299f3acab617581ea504e45fbb6cab24c2b29fsewardj && is_Unop(aa->Iex.Unop.arg->Iex.Unop.arg->Iex.Unop.arg, 54176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj Iop_CmpNEZ32)) { 54186c299f3acab617581ea504e45fbb6cab24c2b29fsewardj return IRExpr_Unop( Iop_CmpwNEZ32, 54196c299f3acab617581ea504e45fbb6cab24c2b29fsewardj aa->Iex.Unop.arg->Iex.Unop.arg 54206c299f3acab617581ea504e45fbb6cab24c2b29fsewardj ->Iex.Unop.arg->Iex.Unop.arg); 54216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj } 54226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj break; 54236c299f3acab617581ea504e45fbb6cab24c2b29fsewardj 5424eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj default: 5425eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj break; 5426eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj } 5427eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj /* no reduction rule applies */ 5428eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return IRExpr_Unop( op, aa ); 5429eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj} 5430eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj 5431f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic IRExpr* atbSubst_Expr ( ATmpInfo* env, IRExpr* e ) 5432695cff9303ef5dc8079117acfd632b44edb1f010sewardj{ 54330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr* e2; 54340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRExpr** args2; 54350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int i; 54360821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5437f6275b741337e8fae0108bb9a96db3498c287fc1sewardj switch (e->tag) { 54380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 54390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_CCall: 5440dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj args2 = shallowCopyIRExprVec(e->Iex.CCall.args); 54410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; args2[i]; i++) 5442f9517d0d452899780e8c34f02bef004ef7c5a163sewardj args2[i] = atbSubst_Expr(env,args2[i]); 5443f9517d0d452899780e8c34f02bef004ef7c5a163sewardj return IRExpr_CCall( 5444f9517d0d452899780e8c34f02bef004ef7c5a163sewardj e->Iex.CCall.cee, 54450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.CCall.retty, 54460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj args2 54470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5448dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Iex_RdTmp: 5449dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e2 = atbSubst_Temp(env, e->Iex.RdTmp.tmp); 54500821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return e2 ? e2 : e; 545199dd03e04a6914d90d5fee727d61d76905334becflorian case Iex_ITE: 545299dd03e04a6914d90d5fee727d61d76905334becflorian return IRExpr_ITE( 545399dd03e04a6914d90d5fee727d61d76905334becflorian atbSubst_Expr(env, e->Iex.ITE.cond), 545499dd03e04a6914d90d5fee727d61d76905334becflorian atbSubst_Expr(env, e->Iex.ITE.iftrue), 545599dd03e04a6914d90d5fee727d61d76905334becflorian atbSubst_Expr(env, e->Iex.ITE.iffalse) 54560821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 545740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj case Iex_Qop: 545840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj return IRExpr_Qop( 545996d7cc3e7d54ad5af2af2821223b21f9a8516a59florian e->Iex.Qop.details->op, 546096d7cc3e7d54ad5af2af2821223b21f9a8516a59florian atbSubst_Expr(env, e->Iex.Qop.details->arg1), 546196d7cc3e7d54ad5af2af2821223b21f9a8516a59florian atbSubst_Expr(env, e->Iex.Qop.details->arg2), 546296d7cc3e7d54ad5af2af2821223b21f9a8516a59florian atbSubst_Expr(env, e->Iex.Qop.details->arg3), 546396d7cc3e7d54ad5af2af2821223b21f9a8516a59florian atbSubst_Expr(env, e->Iex.Qop.details->arg4) 546440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj ); 5465b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Iex_Triop: 5466b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj return IRExpr_Triop( 5467420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian e->Iex.Triop.details->op, 5468420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian atbSubst_Expr(env, e->Iex.Triop.details->arg1), 5469420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian atbSubst_Expr(env, e->Iex.Triop.details->arg2), 5470420bfa9e0f6bc49d7682d334aa61189b4d50f7b8florian atbSubst_Expr(env, e->Iex.Triop.details->arg3) 5471b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj ); 54720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Binop: 5473eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return fold_IRExpr_Binop( 54740821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Binop.op, 5475f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, e->Iex.Binop.arg1), 5476f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, e->Iex.Binop.arg2) 54770821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5478f6275b741337e8fae0108bb9a96db3498c287fc1sewardj case Iex_Unop: 5479eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj return fold_IRExpr_Unop( 54800821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.Unop.op, 5481f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, e->Iex.Unop.arg) 54820821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5483af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Iex_Load: 5484af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return IRExpr_Load( 5485af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj e->Iex.Load.end, 5486af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj e->Iex.Load.ty, 5487f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, e->Iex.Load.addr) 54880821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 54890821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_GetI: 54900821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRExpr_GetI( 54910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.GetI.descr, 5492f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, e->Iex.GetI.ix), 54930821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj e->Iex.GetI.bias 54940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 54950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Const: 54960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj case Iex_Get: 54970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return e; 5498f6275b741337e8fae0108bb9a96db3498c287fc1sewardj default: 5499f6275b741337e8fae0108bb9a96db3498c287fc1sewardj vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); 5500f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vpanic("atbSubst_Expr"); 5501f6275b741337e8fae0108bb9a96db3498c287fc1sewardj } 5502695cff9303ef5dc8079117acfd632b44edb1f010sewardj} 55034345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 5504f9517d0d452899780e8c34f02bef004ef7c5a163sewardj/* Same deal as atbSubst_Expr, except for stmts. */ 5505f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 5506f9517d0d452899780e8c34f02bef004ef7c5a163sewardjstatic IRStmt* atbSubst_Stmt ( ATmpInfo* env, IRStmt* st ) 5507695cff9303ef5dc8079117acfd632b44edb1f010sewardj{ 5508e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj Int i; 5509e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRDirty *d, *d2; 5510e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRCAS *cas, *cas2; 5511d6f38b3f822f7d57adfc0da3410995d85d6a4597florian IRPutI *puti, *puti2; 5512d6f38b3f822f7d57adfc0da3410995d85d6a4597florian 5513f6275b741337e8fae0108bb9a96db3498c287fc1sewardj switch (st->tag) { 55145a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 55155a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj return IRStmt_AbiHint( 5516f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, st->Ist.AbiHint.base), 5517478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj st->Ist.AbiHint.len, 5518478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj atbSubst_Expr(env, st->Ist.AbiHint.nia) 55195a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj ); 5520af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 5521af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return IRStmt_Store( 5522af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj st->Ist.Store.end, 5523f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, st->Ist.Store.addr), 5524f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, st->Ist.Store.data) 55250821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5526cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 5527cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 5528cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_StoreG(sg->end, 5529cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, sg->addr), 5530cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, sg->data), 5531cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, sg->guard)); 5532cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 5533cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 5534cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 5535cfe046e178666280b87da998b1b52ecda03ecd89sewardj return IRStmt_LoadG(lg->end, lg->cvt, lg->dst, 5536cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, lg->addr), 5537cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, lg->alt), 5538cfe046e178666280b87da998b1b52ecda03ecd89sewardj atbSubst_Expr(env, lg->guard)); 5539cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 5540dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 5541dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj return IRStmt_WrTmp( 5542dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj st->Ist.WrTmp.tmp, 5543dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj atbSubst_Expr(env, st->Ist.WrTmp.data) 55440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5545f6275b741337e8fae0108bb9a96db3498c287fc1sewardj case Ist_Put: 55460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRStmt_Put( 55470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st->Ist.Put.offset, 5548f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, st->Ist.Put.data) 55490821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5550f6275b741337e8fae0108bb9a96db3498c287fc1sewardj case Ist_PutI: 5551d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti = st->Ist.PutI.details; 5552d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti2 = mkIRPutI(puti->descr, 5553d6f38b3f822f7d57adfc0da3410995d85d6a4597florian atbSubst_Expr(env, puti->ix), 5554d6f38b3f822f7d57adfc0da3410995d85d6a4597florian puti->bias, 5555d6f38b3f822f7d57adfc0da3410995d85d6a4597florian atbSubst_Expr(env, puti->data)); 5556d6f38b3f822f7d57adfc0da3410995d85d6a4597florian return IRStmt_PutI(puti2); 55570821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5558f6275b741337e8fae0108bb9a96db3498c287fc1sewardj case Ist_Exit: 55590821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRStmt_Exit( 5560f9517d0d452899780e8c34f02bef004ef7c5a163sewardj atbSubst_Expr(env, st->Ist.Exit.guard), 55610821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st->Ist.Exit.jk, 5562c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj st->Ist.Exit.dst, 5563c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj st->Ist.Exit.offsIP 55640821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj ); 5565f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 55662f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj return IRStmt_IMark(st->Ist.IMark.addr, 55672f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj st->Ist.IMark.len, 55682f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj st->Ist.IMark.delta); 5569d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 5570d2445f60726580b450eca68ab40c568f9df338e2sewardj return IRStmt_NoOp(); 5571c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 5572c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj return IRStmt_MBE(st->Ist.MBE.event); 5573e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 5574e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 5575e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas2 = mkIRCAS( 5576e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas->oldHi, cas->oldLo, cas->end, 5577e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj atbSubst_Expr(env, cas->addr), 5578e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas->expdHi ? atbSubst_Expr(env, cas->expdHi) : NULL, 5579e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj atbSubst_Expr(env, cas->expdLo), 5580e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas->dataHi ? atbSubst_Expr(env, cas->dataHi) : NULL, 5581e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj atbSubst_Expr(env, cas->dataLo) 5582e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj ); 5583e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj return IRStmt_CAS(cas2); 5584e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 5585e768e92e054cde495849a5c842a477d287677f78sewardj return IRStmt_LLSC( 5586e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.end, 5587e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.result, 5588e768e92e054cde495849a5c842a477d287677f78sewardj atbSubst_Expr(env, st->Ist.LLSC.addr), 5589e768e92e054cde495849a5c842a477d287677f78sewardj st->Ist.LLSC.storedata 5590e768e92e054cde495849a5c842a477d287677f78sewardj ? atbSubst_Expr(env, st->Ist.LLSC.storedata) : NULL 5591e768e92e054cde495849a5c842a477d287677f78sewardj ); 55927447b5b3355ac4201e3bd717989232cf7a0d748csewardj case Ist_Dirty: 5593f9517d0d452899780e8c34f02bef004ef7c5a163sewardj d = st->Ist.Dirty.details; 55940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj d2 = emptyIRDirty(); 55950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj *d2 = *d; 55960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (d2->mFx != Ifx_None) 5597f9517d0d452899780e8c34f02bef004ef7c5a163sewardj d2->mAddr = atbSubst_Expr(env, d2->mAddr); 5598f9517d0d452899780e8c34f02bef004ef7c5a163sewardj d2->guard = atbSubst_Expr(env, d2->guard); 559974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (i = 0; d2->args[i]; i++) { 560074142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d2->args[i]; 5601ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 560274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj d2->args[i] = atbSubst_Expr(env, arg); 560374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 56040821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj return IRStmt_Dirty(d2); 5605f6275b741337e8fae0108bb9a96db3498c287fc1sewardj default: 5606f6275b741337e8fae0108bb9a96db3498c287fc1sewardj vex_printf("\n"); ppIRStmt(st); vex_printf("\n"); 5607f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vpanic("atbSubst_Stmt"); 56082d04d11c8ca8ff9643bc257780e60a77605b3af7sewardj } 56092d04d11c8ca8ff9643bc257780e60a77605b3af7sewardj} 56102d04d11c8ca8ff9643bc257780e60a77605b3af7sewardj 5611088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorianinline 5612088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorianstatic Bool dirty_helper_stores ( const IRDirty *d ) 5613088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian{ 5614088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian return d->mFx == Ifx_Write || d->mFx == Ifx_Modify; 5615088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian} 5616088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian 5617088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorianinline 5618ca2c3c75784d35d136fc7c952717cdee5063c193sewardjstatic Interval dirty_helper_puts ( 5619ca2c3c75784d35d136fc7c952717cdee5063c193sewardj const IRDirty *d, 5620ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 5621ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl, 5622ca2c3c75784d35d136fc7c952717cdee5063c193sewardj /*OUT*/Bool *requiresPreciseMemExns 5623ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ) 5624088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian{ 5625088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian Int i; 5626740da72e3938e8474234420777c17c1a4be6cb6fflorian Interval interval; 5627088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian 5628088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian /* Passing the guest state pointer opens the door to modifying the 562974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj guest state under the covers. It's not allowed, but let's be 5630088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian extra conservative and assume the worst. */ 563174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (i = 0; d->args[i]; i++) { 5632ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (UNLIKELY(d->args[i]->tag == Iex_GSPTR)) { 563374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj *requiresPreciseMemExns = True; 5634740da72e3938e8474234420777c17c1a4be6cb6fflorian /* Assume all guest state is written. */ 5635740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.present = True; 5636740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.low = 0; 5637740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.high = 0x7FFFFFFF; 5638740da72e3938e8474234420777c17c1a4be6cb6fflorian return interval; 563974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 564062140c196b8c18a23ba0fe54295f0ffa000a0054florian } 5641088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian 5642088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian /* Check the side effects on the guest state */ 5643740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.present = False; 5644740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.low = interval.high = -1; 564562140c196b8c18a23ba0fe54295f0ffa000a0054florian *requiresPreciseMemExns = False; 564662140c196b8c18a23ba0fe54295f0ffa000a0054florian 5647088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian for (i = 0; i < d->nFxState; ++i) { 564862140c196b8c18a23ba0fe54295f0ffa000a0054florian if (d->fxState[i].fx != Ifx_Read) { 564962140c196b8c18a23ba0fe54295f0ffa000a0054florian Int offset = d->fxState[i].offset; 565062140c196b8c18a23ba0fe54295f0ffa000a0054florian Int size = d->fxState[i].size; 565162140c196b8c18a23ba0fe54295f0ffa000a0054florian Int nRepeats = d->fxState[i].nRepeats; 565262140c196b8c18a23ba0fe54295f0ffa000a0054florian Int repeatLen = d->fxState[i].repeatLen; 565362140c196b8c18a23ba0fe54295f0ffa000a0054florian 565474142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj if (preciseMemExnsFn(offset, 5655ca2c3c75784d35d136fc7c952717cdee5063c193sewardj offset + nRepeats * repeatLen + size - 1, 5656ca2c3c75784d35d136fc7c952717cdee5063c193sewardj pxControl)) { 565762140c196b8c18a23ba0fe54295f0ffa000a0054florian *requiresPreciseMemExns = True; 565862140c196b8c18a23ba0fe54295f0ffa000a0054florian } 5659740da72e3938e8474234420777c17c1a4be6cb6fflorian update_interval(&interval, offset, 5660740da72e3938e8474234420777c17c1a4be6cb6fflorian offset + nRepeats * repeatLen + size - 1); 566162140c196b8c18a23ba0fe54295f0ffa000a0054florian } 5662088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian } 5663088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian 5664740da72e3938e8474234420777c17c1a4be6cb6fflorian return interval; 566562140c196b8c18a23ba0fe54295f0ffa000a0054florian} 566662140c196b8c18a23ba0fe54295f0ffa000a0054florian 5667ca2c3c75784d35d136fc7c952717cdee5063c193sewardj/* Return an interval if st modifies the guest state. Via 5668ca2c3c75784d35d136fc7c952717cdee5063c193sewardj requiresPreciseMemExns return whether or not that modification 5669ca2c3c75784d35d136fc7c952717cdee5063c193sewardj requires precise exceptions. */ 5670ca2c3c75784d35d136fc7c952717cdee5063c193sewardjstatic Interval stmt_modifies_guest_state ( 5671ca2c3c75784d35d136fc7c952717cdee5063c193sewardj IRSB *bb, const IRStmt *st, 5672ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 5673ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl, 5674ca2c3c75784d35d136fc7c952717cdee5063c193sewardj /*OUT*/Bool *requiresPreciseMemExns 5675ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ) 567662140c196b8c18a23ba0fe54295f0ffa000a0054florian{ 5677740da72e3938e8474234420777c17c1a4be6cb6fflorian Interval interval; 5678740da72e3938e8474234420777c17c1a4be6cb6fflorian 567962140c196b8c18a23ba0fe54295f0ffa000a0054florian switch (st->tag) { 568062140c196b8c18a23ba0fe54295f0ffa000a0054florian case Ist_Put: { 568162140c196b8c18a23ba0fe54295f0ffa000a0054florian Int offset = st->Ist.Put.offset; 568262140c196b8c18a23ba0fe54295f0ffa000a0054florian Int size = sizeofIRType(typeOfIRExpr(bb->tyenv, st->Ist.Put.data)); 568362140c196b8c18a23ba0fe54295f0ffa000a0054florian 5684ca2c3c75784d35d136fc7c952717cdee5063c193sewardj *requiresPreciseMemExns 5685ca2c3c75784d35d136fc7c952717cdee5063c193sewardj = preciseMemExnsFn(offset, offset + size - 1, pxControl); 5686740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.present = True; 5687740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.low = offset; 5688740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.high = offset + size - 1; 5689740da72e3938e8474234420777c17c1a4be6cb6fflorian return interval; 569062140c196b8c18a23ba0fe54295f0ffa000a0054florian } 569162140c196b8c18a23ba0fe54295f0ffa000a0054florian 569262140c196b8c18a23ba0fe54295f0ffa000a0054florian case Ist_PutI: { 569362140c196b8c18a23ba0fe54295f0ffa000a0054florian IRRegArray *descr = st->Ist.PutI.details->descr; 569462140c196b8c18a23ba0fe54295f0ffa000a0054florian Int offset = descr->base; 569562140c196b8c18a23ba0fe54295f0ffa000a0054florian Int size = sizeofIRType(descr->elemTy); 569662140c196b8c18a23ba0fe54295f0ffa000a0054florian 569762140c196b8c18a23ba0fe54295f0ffa000a0054florian /* We quietly assume here that all segments are contiguous and there 569862140c196b8c18a23ba0fe54295f0ffa000a0054florian are no holes. This is to avoid a loop. The assumption is conservative 569962140c196b8c18a23ba0fe54295f0ffa000a0054florian in the sense that we might report that precise memory exceptions are 570062140c196b8c18a23ba0fe54295f0ffa000a0054florian needed when in fact they are not. */ 5701ca2c3c75784d35d136fc7c952717cdee5063c193sewardj *requiresPreciseMemExns 5702ca2c3c75784d35d136fc7c952717cdee5063c193sewardj = preciseMemExnsFn(offset, offset + descr->nElems * size - 1, 5703ca2c3c75784d35d136fc7c952717cdee5063c193sewardj pxControl); 5704740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.present = True; 5705740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.low = offset; 5706740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.high = offset + descr->nElems * size - 1; 5707740da72e3938e8474234420777c17c1a4be6cb6fflorian return interval; 570862140c196b8c18a23ba0fe54295f0ffa000a0054florian } 570962140c196b8c18a23ba0fe54295f0ffa000a0054florian 571062140c196b8c18a23ba0fe54295f0ffa000a0054florian case Ist_Dirty: 5711ca2c3c75784d35d136fc7c952717cdee5063c193sewardj return dirty_helper_puts(st->Ist.Dirty.details, 5712ca2c3c75784d35d136fc7c952717cdee5063c193sewardj preciseMemExnsFn, pxControl, 571362140c196b8c18a23ba0fe54295f0ffa000a0054florian requiresPreciseMemExns); 571462140c196b8c18a23ba0fe54295f0ffa000a0054florian 571562140c196b8c18a23ba0fe54295f0ffa000a0054florian default: 571662140c196b8c18a23ba0fe54295f0ffa000a0054florian *requiresPreciseMemExns = False; 5717740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.present = False; 5718740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.low = -1; 5719740da72e3938e8474234420777c17c1a4be6cb6fflorian interval.high = -1; 5720740da72e3938e8474234420777c17c1a4be6cb6fflorian return interval; 572162140c196b8c18a23ba0fe54295f0ffa000a0054florian } 5722088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian} 5723088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian 5724ca2c3c75784d35d136fc7c952717cdee5063c193sewardj/* notstatic */ Addr ado_treebuild_BB ( 5725ca2c3c75784d35d136fc7c952717cdee5063c193sewardj IRSB* bb, 5726ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 5727ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl 5728ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ) 57290821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj{ 5730f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Int i, j, k, m; 5731740da72e3938e8474234420777c17c1a4be6cb6fflorian Bool stmtStores, invalidateMe; 5732740da72e3938e8474234420777c17c1a4be6cb6fflorian Interval putInterval; 57330821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st; 57340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj IRStmt* st2; 5735f9517d0d452899780e8c34f02bef004ef7c5a163sewardj ATmpInfo env[A_NENV]; 57362d04d11c8ca8ff9643bc257780e60a77605b3af7sewardj 5737c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj Bool max_ga_known = False; 5738dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian Addr max_ga = 0; 5739c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 57400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj Int n_tmps = bb->tyenv->types_used; 5741d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian UShort* uses = LibVEX_Alloc_inline(n_tmps * sizeof(UShort)); 5742f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 57430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Phase 1. Scan forwards in bb, counting use occurrences of each 5744c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj temp. Also count occurrences in the bb->next field. Take the 5745c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj opportunity to also find the maximum guest address in the block, 5746c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj since that will be needed later for deciding when we can safely 5747c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj elide event checks. */ 5748f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 5749f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; i < n_tmps; i++) 5750f9517d0d452899780e8c34f02bef004ef7c5a163sewardj uses[i] = 0; 5751f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 57520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb->stmts_used; i++) { 57530821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 5754c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj switch (st->tag) { 5755c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ist_NoOp: 5756c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj continue; 5757c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj case Ist_IMark: { 5758dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian UInt len = st->Ist.IMark.len; 5759dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian Addr mga = st->Ist.IMark.addr + (len < 1 ? 1 : len) - 1; 5760c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj max_ga_known = True; 5761c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj if (mga > max_ga) 5762c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj max_ga = mga; 5763c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj break; 5764c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 5765c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj default: 5766c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj break; 5767c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj } 5768f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Stmt( uses, st ); 57690821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 5770f9517d0d452899780e8c34f02bef004ef7c5a163sewardj aoccCount_Expr(uses, bb->next ); 5771f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 57720821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# if 0 5773f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; i < n_tmps; i++) { 5774f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (uses[i] == 0) 57750821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 5776f9517d0d452899780e8c34f02bef004ef7c5a163sewardj ppIRTemp( (IRTemp)i ); 5777f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vex_printf(" used %d\n", (Int)uses[i] ); 57780821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 57790821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj# endif 5780f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 5781f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Phase 2. Scan forwards in bb. For each statement in turn: 5782f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 5783f9517d0d452899780e8c34f02bef004ef7c5a163sewardj If the env is full, emit the end element. This guarantees 5784f9517d0d452899780e8c34f02bef004ef7c5a163sewardj there is at least one free slot in the following. 5785695cff9303ef5dc8079117acfd632b44edb1f010sewardj 5786f9517d0d452899780e8c34f02bef004ef7c5a163sewardj On seeing 't = E', occ(t)==1, 5787f9517d0d452899780e8c34f02bef004ef7c5a163sewardj let E'=env(E) 5788f9517d0d452899780e8c34f02bef004ef7c5a163sewardj delete this stmt 5789f9517d0d452899780e8c34f02bef004ef7c5a163sewardj add t -> E' to the front of the env 5790f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Examine E' and set the hints for E' appropriately 57910821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj (doesLoad? doesGet?) 5792695cff9303ef5dc8079117acfd632b44edb1f010sewardj 5793f9517d0d452899780e8c34f02bef004ef7c5a163sewardj On seeing any other stmt, 57940821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj let stmt' = env(stmt) 57950821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj remove from env any 't=E' binds invalidated by stmt 57960821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj emit the invalidated stmts 57970821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj emit stmt' 5798f9517d0d452899780e8c34f02bef004ef7c5a163sewardj compact any holes in env 5799f9517d0d452899780e8c34f02bef004ef7c5a163sewardj by sliding entries towards the front 5800695cff9303ef5dc8079117acfd632b44edb1f010sewardj 5801f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Finally, apply env to bb->next. 58020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 5803695cff9303ef5dc8079117acfd632b44edb1f010sewardj 5804f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (i = 0; i < A_NENV; i++) { 5805f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[i].bindee = NULL; 5806f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[i].binder = IRTemp_INVALID; 5807f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 5808f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 58090821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* The stmts in bb are being reordered, and we are guaranteed to 58100821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj end up with no more than the number we started with. Use i to 58110821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj be the cursor of the current stmt examined and j <= i to be that 58120821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for the current stmt being written. 58130821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj */ 58140821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj j = 0; 58150821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj for (i = 0; i < bb->stmts_used; i++) { 5816f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 58170821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj st = bb->stmts[i]; 58188bee6d15808653a71717c256a3abe96993439d25sewardj if (st->tag == Ist_NoOp) 58190821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj continue; 58200821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5821f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Ensure there's at least one space in the env, by emitting 5822f9517d0d452899780e8c34f02bef004ef7c5a163sewardj the oldest binding if necessary. */ 5823f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (env[A_NENV-1].bindee != NULL) { 5824dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[j] = IRStmt_WrTmp( env[A_NENV-1].binder, 5825dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj env[A_NENV-1].bindee ); 5826f9517d0d452899780e8c34f02bef004ef7c5a163sewardj j++; 5827f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vassert(j <= i); 5828f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[A_NENV-1].bindee = NULL; 5829f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 5830f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5831f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Consider current stmt. */ 5832dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->tag == Ist_WrTmp && uses[st->Ist.WrTmp.tmp] <= 1) { 5833633274098fafebdc79cf1c8a1ef7f9a9914669f1sewardj IRExpr *e, *e2; 5834f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5835f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* optional extra: dump dead bindings as we find them. 5836f9517d0d452899780e8c34f02bef004ef7c5a163sewardj Removes the need for a prior dead-code removal pass. */ 5837dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (uses[st->Ist.WrTmp.tmp] == 0) { 5838b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (0) vex_printf("DEAD binding\n"); 5839f9517d0d452899780e8c34f02bef004ef7c5a163sewardj continue; /* for (i = 0; i < bb->stmts_used; i++) loop */ 58400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 5841dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj vassert(uses[st->Ist.WrTmp.tmp] == 1); 5842f9517d0d452899780e8c34f02bef004ef7c5a163sewardj 5843f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* ok, we have 't = E', occ(t)==1. Do the abovementioned 5844f9517d0d452899780e8c34f02bef004ef7c5a163sewardj actions. */ 5845dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj e = st->Ist.WrTmp.data; 5846633274098fafebdc79cf1c8a1ef7f9a9914669f1sewardj e2 = atbSubst_Expr(env, e); 5847dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj addToEnvFront(env, st->Ist.WrTmp.tmp, e2); 5848740da72e3938e8474234420777c17c1a4be6cb6fflorian setHints_Expr(&env[0].doesLoad, &env[0].getInterval, e2); 5849f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* don't advance j, as we are deleting this stmt and instead 5850f9517d0d452899780e8c34f02bef004ef7c5a163sewardj holding it temporarily in the env. */ 5851f9517d0d452899780e8c34f02bef004ef7c5a163sewardj continue; /* for (i = 0; i < bb->stmts_used; i++) loop */ 58520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } 5853f6275b741337e8fae0108bb9a96db3498c287fc1sewardj 58540821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* we get here for any other kind of statement. */ 58550821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* 'use up' any bindings required by the current statement. */ 5856f9517d0d452899780e8c34f02bef004ef7c5a163sewardj st2 = atbSubst_Stmt(env, st); 58573e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj 5858f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Now, before this stmt, dump any bindings in env that it 5859f9517d0d452899780e8c34f02bef004ef7c5a163sewardj invalidates. These need to be dumped in the order in which 5860f9517d0d452899780e8c34f02bef004ef7c5a163sewardj they originally entered env -- that means from oldest to 5861f9517d0d452899780e8c34f02bef004ef7c5a163sewardj youngest. */ 58623e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj 5863740da72e3938e8474234420777c17c1a4be6cb6fflorian /* putInterval/stmtStores characterise what the stmt under 5864e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj consideration does, or might do (sidely safe @ True). */ 586562140c196b8c18a23ba0fe54295f0ffa000a0054florian 586662140c196b8c18a23ba0fe54295f0ffa000a0054florian Bool putRequiresPreciseMemExns; 5867ca2c3c75784d35d136fc7c952717cdee5063c193sewardj putInterval = stmt_modifies_guest_state( 5868ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb, st, preciseMemExnsFn, pxControl, 5869ca2c3c75784d35d136fc7c952717cdee5063c193sewardj &putRequiresPreciseMemExns 5870ca2c3c75784d35d136fc7c952717cdee5063c193sewardj ); 5871e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj 5872e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj /* be True if this stmt writes memory or might do (==> we don't 5873e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj want to reorder other loads or stores relative to it). Also, 5874e768e92e054cde495849a5c842a477d287677f78sewardj both LL and SC fall under this classification, since we 5875e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj really ought to be conservative and not reorder any other 5876e768e92e054cde495849a5c842a477d287677f78sewardj memory transactions relative to them. */ 5877e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj stmtStores 5878e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj = toBool( st->tag == Ist_Store 5879088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian || (st->tag == Ist_Dirty 5880088809c82b9d92d415df3a0a947bc3c6dd4ccbbeflorian && dirty_helper_stores(st->Ist.Dirty.details)) 58810f6219808968a4bf2b597a7e5ff2258fa2dda505sewardj || st->tag == Ist_LLSC 58820f6219808968a4bf2b597a7e5ff2258fa2dda505sewardj || st->tag == Ist_CAS ); 58833e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj 5884f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (k = A_NENV-1; k >= 0; k--) { 5885f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (env[k].bindee == NULL) 5886f9517d0d452899780e8c34f02bef004ef7c5a163sewardj continue; 5887f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Compare the actions of this stmt with the actions of 5888f9517d0d452899780e8c34f02bef004ef7c5a163sewardj binding 'k', to see if they invalidate the binding. */ 5889f9517d0d452899780e8c34f02bef004ef7c5a163sewardj invalidateMe 58909d2e769a9368d2b22c32a4764a70e9da38769628sewardj = toBool( 58919d2e769a9368d2b22c32a4764a70e9da38769628sewardj /* a store invalidates loaded data */ 5892f9517d0d452899780e8c34f02bef004ef7c5a163sewardj (env[k].doesLoad && stmtStores) 5893740da72e3938e8474234420777c17c1a4be6cb6fflorian /* a put invalidates get'd data, if they overlap */ 5894740da72e3938e8474234420777c17c1a4be6cb6fflorian || ((env[k].getInterval.present && putInterval.present) && 5895740da72e3938e8474234420777c17c1a4be6cb6fflorian intervals_overlap(env[k].getInterval, putInterval)) 589662140c196b8c18a23ba0fe54295f0ffa000a0054florian /* a put invalidates loaded data. That means, in essense, that 589762140c196b8c18a23ba0fe54295f0ffa000a0054florian a load expression cannot be substituted into a statement 589862140c196b8c18a23ba0fe54295f0ffa000a0054florian that follows the put. But there is nothing wrong doing so 589962140c196b8c18a23ba0fe54295f0ffa000a0054florian except when the put statement requries precise exceptions. 590062140c196b8c18a23ba0fe54295f0ffa000a0054florian Think of a load that is moved past a put where the put 590162140c196b8c18a23ba0fe54295f0ffa000a0054florian updates the IP in the guest state. If the load generates 590262140c196b8c18a23ba0fe54295f0ffa000a0054florian a segfault, the wrong address (line number) would be 590362140c196b8c18a23ba0fe54295f0ffa000a0054florian reported. */ 5904740da72e3938e8474234420777c17c1a4be6cb6fflorian || (env[k].doesLoad && putInterval.present && 5905740da72e3938e8474234420777c17c1a4be6cb6fflorian putRequiresPreciseMemExns) 5906c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj /* probably overly conservative: a memory bus event 59073e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj invalidates absolutely everything, so that all 59083e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj computation prior to it is forced to complete before 5909c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj proceeding with the event (fence,lock,unlock). */ 5910c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj || st->tag == Ist_MBE 59115a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj /* also be (probably overly) paranoid re AbiHints */ 59125a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj || st->tag == Ist_AbiHint 59139d2e769a9368d2b22c32a4764a70e9da38769628sewardj ); 5914f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (invalidateMe) { 5915dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj bb->stmts[j] = IRStmt_WrTmp( env[k].binder, env[k].bindee ); 5916f9517d0d452899780e8c34f02bef004ef7c5a163sewardj j++; 5917f9517d0d452899780e8c34f02bef004ef7c5a163sewardj vassert(j <= i); 5918f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[k].bindee = NULL; 5919f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 59202d04d11c8ca8ff9643bc257780e60a77605b3af7sewardj } 5921695cff9303ef5dc8079117acfd632b44edb1f010sewardj 5922f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* Slide in-use entries in env up to the front */ 5923f9517d0d452899780e8c34f02bef004ef7c5a163sewardj m = 0; 5924f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (k = 0; k < A_NENV; k++) { 5925f9517d0d452899780e8c34f02bef004ef7c5a163sewardj if (env[k].bindee != NULL) { 5926f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[m] = env[k]; 5927f9517d0d452899780e8c34f02bef004ef7c5a163sewardj m++; 5928f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 5929f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 5930f9517d0d452899780e8c34f02bef004ef7c5a163sewardj for (m = m; m < A_NENV; m++) { 5931f9517d0d452899780e8c34f02bef004ef7c5a163sewardj env[m].bindee = NULL; 5932f9517d0d452899780e8c34f02bef004ef7c5a163sewardj } 5933695cff9303ef5dc8079117acfd632b44edb1f010sewardj 59340821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* finally, emit the substituted statement */ 59350821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts[j] = st2; 5936f9517d0d452899780e8c34f02bef004ef7c5a163sewardj /* vex_printf("**2 "); ppIRStmt(bb->stmts[j]); vex_printf("\n"); */ 59370821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj j++; 59380821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 59390821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj vassert(j <= i+1); 59400821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj } /* for each stmt in the original bb ... */ 59410821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 59420821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* Finally ... substitute the ->next field as much as possible, and 59430821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj dump any left-over bindings. Hmm. Perhaps there should be no 59440821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj left over bindings? Or any left-over bindings are 59450821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj by definition dead? */ 5946f9517d0d452899780e8c34f02bef004ef7c5a163sewardj bb->next = atbSubst_Expr(env, bb->next); 59470821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj bb->stmts_used = j; 5948c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj 5949dcd6d236c9aef7d4c84369d4c51f6b92ac910127florian return max_ga_known ? max_ga : ~(Addr)0; 5950695cff9303ef5dc8079117acfd632b44edb1f010sewardj} 5951695cff9303ef5dc8079117acfd632b44edb1f010sewardj 59520821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 5953695cff9303ef5dc8079117acfd632b44edb1f010sewardj/*---------------------------------------------------------------*/ 595416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/*--- MSVC specific transformation hacks ---*/ 595516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/*---------------------------------------------------------------*/ 595616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 595716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* The purpose of all this is to find MSVC's idiom for non-constant 595816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj bitfield assignment, "a ^ ((a ^ b) & c)", and transform it into 595916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj gcc's idiom "(a & ~c) | (b & c)". Motivation is that Memcheck has 596016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj generates a lot of false positives from the MSVC version because it 596116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj doesn't understand that XORing an undefined bit with itself gives a 596216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj defined result. 596316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 596416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj This isn't a problem for the simple case "x ^ x", because iropt 596516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj folds it to a constant zero before Memcheck ever sees it. But in 596616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj this case we have an intervening "& c" which defeats the simple 596716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case. So we have to carefully inspect all expressions rooted at an 596816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj XOR to see if any of them match "a ^ ((a ^ b) & c)", or any of the 596916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 7 other variants resulting from swapping the order of arguments to 597016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj the three binary operations. If we get a match, we then replace 597116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj the tree with "(a & ~c) | (b & c)", and Memcheck is happy. 597216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 597316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj The key difficulty is to spot the two uses of "a". To normalise 597416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj the IR to maximise the chances of success, we first do a CSE pass, 597516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj with CSEing of loads enabled, since the two "a" expressions may be 597616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj loads, which need to be commoned up. Then we do a constant folding 597716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj pass, so as to remove any tmp-to-tmp assignment chains that would 597816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj make matching the original expression more difficult. 597916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj*/ 598016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 598116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 598216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* Helper function for debug printing */ 598316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj__attribute__((unused)) 598416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic void print_flat_expr ( IRExpr** env, IRExpr* e ) 598516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 598616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (e == NULL) { 598716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("?"); 598816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return; 598916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 599016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj switch (e->tag) { 599116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_Binop: { 599216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ppIROp(e->Iex.Binop.op); 599316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("("); 599416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj print_flat_expr(env, e->Iex.Binop.arg1); 599516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf(","); 599616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj print_flat_expr(env, e->Iex.Binop.arg2); 599716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf(")"); 599816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 599916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 600016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_Unop: { 600116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ppIROp(e->Iex.Unop.op); 600216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("("); 600316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj print_flat_expr(env, e->Iex.Unop.arg); 600416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf(")"); 600516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 600616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 600716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_RdTmp: 600816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ppIRTemp(e->Iex.RdTmp.tmp); 600916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("="); 6010ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes print_flat_expr(env, chase1(env, e)); 601116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 601216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_Const: 601316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_CCall: 601416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_Load: 601516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_ITE: 601616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iex_Get: 601716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ppIRExpr(e); 601816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 601916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj default: 602016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("FAIL: "); ppIRExpr(e); vex_printf("\n"); 602116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(0); 602216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 602316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 602416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 602516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* Spot a ^ ((a ^ b) & c) for a,b and c tmp-or-const (atoms) 602616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj or any of the other 7 variants generated by switching the order 602716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj of arguments to the outer ^, the inner ^ and the &. 602816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj*/ 602916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic UInt spotBitfieldAssignment ( /*OUT*/IRExpr** aa, /*OUT*/IRExpr** bb, 603016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /*OUT*/IRExpr** cc, 603116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr** env, IRExpr* e, 603216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IROp opAND, IROp opXOR) 603316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 603416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# define ISBIN(_e,_op) ((_e) && (_e)->tag == Iex_Binop \ 603516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj && (_e)->Iex.Binop.op == (_op)) 603616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# define ISATOM(_e) isIRAtom(_e) 603716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# define STEP(_e) chase1(env, (_e)) 603816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# define LL(_e) ((_e)->Iex.Binop.arg1) 603916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# define RR(_e) ((_e)->Iex.Binop.arg2) 604016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 604116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr *a1, *and, *xor, *c, *a2bL, *a2bR; 604216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 604316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* This is common to all 8 cases */ 604416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(e, opXOR)) goto fail; 604516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 604616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* -----and------ */ 604716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* --xor--- */ 604816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 1: a1 ^ ((a2 ^ b) & c) */ 604916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 2: a1 ^ ((b ^ a2) & c) */ 605016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = and = xor = c = a2bL = a2bR = NULL; 605116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 605216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = LL(e); 605316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj and = STEP(RR(e)); 605416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(and, opAND)) goto v34; 605516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj xor = STEP(LL(and)); 605616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj c = RR(and); 605716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(xor, opXOR)) goto v34; 605816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bL = LL(xor); 605916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bR = RR(xor); 606016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 606116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bL) && !eqIRAtom(a1, a2bR)) { 606216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 606316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bR; 606416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 606516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 1; 606616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 606716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bR) && !eqIRAtom(a1, a2bL)) { 606816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 606916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bL; 607016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 607116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 2; 607216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 607316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 607416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj v34: 607516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* -----and------ */ 607616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* --xor--- */ 607716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 3: ((a2 ^ b) & c) ^ a1 */ 607816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 4: ((b ^ a2) & c) ^ a1 */ 607916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = and = xor = c = a2bL = a2bR = NULL; 608016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 608116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = RR(e); 608216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj and = STEP(LL(e)); 608316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(and, opAND)) goto v56; 608416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj xor = STEP(LL(and)); 608516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj c = RR(and); 608616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(xor, opXOR)) goto v56; 608716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bL = LL(xor); 608816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bR = RR(xor); 608916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 609016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bL) && !eqIRAtom(a1, a2bR)) { 609116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 609216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bR; 609316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 609416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 3; 609516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 609616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bR) && !eqIRAtom(a1, a2bL)) { 609716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 609816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bL; 609916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 610016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 4; 610116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 610216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 610316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj v56: 610416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* -----and------ */ 610516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* --xor--- */ 610616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 5: a1 ^ (c & (a2 ^ b)) */ 610716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 6: a1 ^ (c & (b ^ a2)) */ 610816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = and = xor = c = a2bL = a2bR = NULL; 610916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 611016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = LL(e); 611116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj and = STEP(RR(e)); 611216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(and, opAND)) goto v78; 611316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj xor = STEP(RR(and)); 611416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj c = LL(and); 611516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(xor, opXOR)) goto v78; 611616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bL = LL(xor); 611716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bR = RR(xor); 611816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 611916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bL) && !eqIRAtom(a1, a2bR)) { 612016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 612116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bR; 612216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 612316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(5-5); // ATC 612416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 5; 612516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 612616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bR) && !eqIRAtom(a1, a2bL)) { 612716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 612816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bL; 612916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 613016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(6-6); // ATC 613116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 6; 613216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 613316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 613416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj v78: 613516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* -----and------ */ 613616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* --xor--- */ 613716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 7: (c & (a2 ^ b)) ^ a1 */ 613816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* find variant 8: (c & (b ^ a2)) ^ a1 */ 613916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = and = xor = c = a2bL = a2bR = NULL; 614016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 614116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a1 = RR(e); 614216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj and = STEP(LL(e)); 614316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(and, opAND)) goto fail; 614416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj xor = STEP(RR(and)); 614516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj c = LL(and); 614616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (!ISBIN(xor, opXOR)) goto fail; 614716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bL = LL(xor); 614816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj a2bR = RR(xor); 614916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 615016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bL) && !eqIRAtom(a1, a2bR)) { 615116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 615216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bR; 615316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 615416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 7; 615516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 615616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (eqIRAtom(a1, a2bR) && !eqIRAtom(a1, a2bL)) { 615716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *aa = a1; 615816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *bb = a2bL; 615916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj *cc = c; 616016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 8; 616116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 616216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 616316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj fail: 616416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return 0; 616516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 616616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# undef ISBIN 616716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# undef ISATOM 616816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# undef STEP 616916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# undef LL 617016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj# undef RR 617116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 617216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 617316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* If |e| is of the form a ^ ((a ^ b) & c) (or any of the 7 other 617416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj variants thereof generated by switching arguments around), return 617516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj the IRExpr* for (a & ~c) | (b & c). Else return NULL. */ 617616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic IRExpr* do_XOR_TRANSFORMS_IRExpr ( IRExpr** env, IRExpr* e ) 617716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 617816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (e->tag != Iex_Binop) 617916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return NULL; 618016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 618116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj const HChar* tyNm = NULL; 618216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IROp opOR = Iop_INVALID; 618316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IROp opAND = Iop_INVALID; 618416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IROp opNOT = Iop_INVALID; 618516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IROp opXOR = Iop_INVALID; 618616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj switch (e->Iex.Binop.op) { 618716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iop_Xor32: 618816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj tyNm = "I32"; 618916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opOR = Iop_Or32; opAND = Iop_And32; 619016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opNOT = Iop_Not32; opXOR = Iop_Xor32; 619116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 619216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iop_Xor16: 619316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj tyNm = "I16"; 619416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opOR = Iop_Or16; opAND = Iop_And16; 619516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opNOT = Iop_Not16; opXOR = Iop_Xor16; 619616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 619716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Iop_Xor8: 619816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj tyNm = "I8"; 619916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opOR = Iop_Or8; opAND = Iop_And8; 620016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opNOT = Iop_Not8; opXOR = Iop_Xor8; 620116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 620216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj default: 620316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return NULL; 620416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 620516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 620616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr* aa = NULL; 620716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr* bb = NULL; 620816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr* cc = NULL; 620916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj UInt variant = spotBitfieldAssignment(&aa, &bb, &cc, env, e, opAND, opXOR); 621016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (variant > 0) { 621116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj static UInt ctr = 0; 621216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (0) 621316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("XXXXXXXXXX Bitfield Assignment number %u, " 621416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj "type %s, variant %u\n", 621516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ++ctr, tyNm, variant); 621616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* It's vitally important that the returned aa, bb and cc are 621716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj atoms -- either constants or tmps. If it's anything else 621816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj (eg, a GET) then incorporating them in a tree at this point 621916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj in the SB may erroneously pull them forwards (eg of a PUT 622016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj that originally was after the GET) and so transform the IR 622116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj wrongly. spotBitfieldAssignment should guarantee only to 622216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj give us atoms, but we check here anyway. */ 622316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(aa && isIRAtom(aa)); 622416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(bb && isIRAtom(bb)); 622516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(cc && isIRAtom(cc)); 622616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return IRExpr_Binop( 622716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj opOR, 622816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr_Binop(opAND, aa, IRExpr_Unop(opNOT, cc)), 622916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr_Binop(opAND, bb, cc) 623016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj ); 623116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 623216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return NULL; 623316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 623416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 623516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 623616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/* SB is modified in-place. Visit all the IRExprs and, for those 623716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj which are allowed to be non-atomic, perform the XOR transform if 623816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj possible. This makes |sb| be non-flat, but that's ok, the caller 623916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj can re-flatten it. Returns True iff any changes were made. */ 624016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic Bool do_XOR_TRANSFORM_IRSB ( IRSB* sb ) 624116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 624216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj Int i; 624316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj Bool changed = False; 624416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 624516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* Make the tmp->expr environment, so we can use it for 624616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj chasing expressions. */ 624716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj Int n_tmps = sb->tyenv->types_used; 6248d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian IRExpr** env = LibVEX_Alloc_inline(n_tmps * sizeof(IRExpr*)); 624916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj for (i = 0; i < n_tmps; i++) 625016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj env[i] = NULL; 625116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 625216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj for (i = 0; i < sb->stmts_used; i++) { 625316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRStmt* st = sb->stmts[i]; 625416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (st->tag != Ist_WrTmp) 625516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj continue; 625616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRTemp t = st->Ist.WrTmp.tmp; 625716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(t >= 0 && t < n_tmps); 625816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj env[t] = st->Ist.WrTmp.data; 625916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 626016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 626116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj for (i = 0; i < sb->stmts_used; i++) { 626216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRStmt* st = sb->stmts[i]; 626316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 626416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj switch (st->tag) { 626516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_AbiHint: 626616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.AbiHint.base)); 626716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.AbiHint.nia)); 626816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 626916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_Put: 627016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.Put.data)); 627116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 627216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_PutI: { 627316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRPutI* puti = st->Ist.PutI.details; 627416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(puti->ix)); 627516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(puti->data)); 627616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 627716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 627816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_WrTmp: { 627916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /* This is the one place where an expr (st->Ist.WrTmp.data) is 628016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj allowed to be more than just a constant or a tmp. */ 628116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr* mb_new_data 628216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj = do_XOR_TRANSFORMS_IRExpr(env, st->Ist.WrTmp.data); 628316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (mb_new_data) { 628416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj //ppIRSB(sb); 628516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj st->Ist.WrTmp.data = mb_new_data; 628616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj //ppIRSB(sb); 628716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj changed = True; 628816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 628916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 629016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 629116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_Store: 629216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.Store.addr)); 629316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.Store.data)); 629416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 629516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_StoreG: { 629616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRStoreG* sg = st->Ist.StoreG.details; 629716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(sg->addr)); 629816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(sg->data)); 629916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(sg->guard)); 630016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 630116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 630216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_LoadG: { 630316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRLoadG* lg = st->Ist.LoadG.details; 630416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(lg->addr)); 630516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(lg->alt)); 630616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(lg->guard)); 630716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 630816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 630916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_CAS: { 631016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRCAS* cas = st->Ist.CAS.details; 631116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(cas->addr)); 631216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(cas->expdHi == NULL || isIRAtom(cas->expdHi)); 631316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(cas->expdLo)); 631416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(cas->dataHi == NULL || isIRAtom(cas->dataHi)); 631516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(cas->dataLo)); 631616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 631716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 631816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_LLSC: 631916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.LLSC.addr)); 632016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (st->Ist.LLSC.storedata) 632116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.LLSC.storedata)); 632216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 632316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_Dirty: { 632416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRDirty* d = st->Ist.Dirty.details; 632516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (d->mFx != Ifx_None) { 632616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(d->mAddr)); 632716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 632816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(d->guard)); 632916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj for (Int j = 0; d->args[j]; j++) { 633016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj IRExpr* arg = d->args[j]; 6331ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) { 633216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(arg)); 633316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 633416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 633516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 633616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 633716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_IMark: 633816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_NoOp: 633916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_MBE: 634016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 634116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj case Ist_Exit: 634216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(st->Ist.Exit.guard)); 634316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj break; 634416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj default: 634516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vex_printf("\n"); ppIRStmt(st); 634616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vpanic("do_XOR_TRANSFORMS_IRSB"); 634716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 634816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 634916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 635016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj vassert(isIRAtom(sb->next)); 635116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return changed; 635216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 635316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 635416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 635516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardjstatic IRSB* do_MSVC_HACKS ( IRSB* sb ) 635616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj{ 635716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // Normalise as much as we can. This is the one-and-only place 635816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // where we call do_cse_BB with allowLoadsToBeCSEd set to True. 635916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj Bool any_cse_changes = do_cse_BB( sb, True/*allowLoadsToBeCSEd*/ ); 636016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (any_cse_changes) { 636116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // CSEing might have created dead code. Remove it. 636216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj sb = cprop_BB ( sb ); 636316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj do_deadcode_BB(sb); 636416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 636516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 636616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // Visit all atoms, do the transformation proper. bb is modified 636716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // in-place. 636816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj Bool changed = do_XOR_TRANSFORM_IRSB(sb); 636916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 637016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (changed) { 637116caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // The transformation generates non-flat expressions, so we now 637216caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // need to re-flatten the block. 637316caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj sb = flatten_BB(sb); 637416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj } 637516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 637616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj return sb; 637716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj} 637816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 637916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 638016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj/*---------------------------------------------------------------*/ 6381695cff9303ef5dc8079117acfd632b44edb1f010sewardj/*--- iropt main ---*/ 6382695cff9303ef5dc8079117acfd632b44edb1f010sewardj/*---------------------------------------------------------------*/ 6383695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6384b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic Bool iropt_verbose = False; /* True; */ 6385695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6386695cff9303ef5dc8079117acfd632b44edb1f010sewardj 63874345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj/* Do a simple cleanup pass on bb. This is: redundant Get removal, 63884345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj redundant Put removal, constant propagation, dead code removal, 63894345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj clean helper specialisation, and dead code removal (again). 6390b92307503d4fb9265136e182d10c42ebb9dd8272sewardj*/ 6391695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6392d721703a7a904a66c49d0e6318c184d0076b40b0sewardj 63934345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardjstatic 6394dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjIRSB* cheap_transformations ( 6395dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB* bb, 63961ff4756e1731485e6bf3cd96717cd8398daec1f2florian IRExpr* (*specHelper) (const HChar*, IRExpr**, IRStmt**, Int), 6397ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 6398ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl 63998d2291c9199adf1d0d9a5c684932d7ffe6d8e0c9sewardj ) 64004345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj{ 64014345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj redundant_get_removal_BB ( bb ); 64024345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 6403d721703a7a904a66c49d0e6318c184d0076b40b0sewardj vex_printf("\n========= REDUNDANT GET\n\n" ); 6404dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 6405d721703a7a904a66c49d0e6318c184d0076b40b0sewardj } 6406044a215317abdd84dd7224a416595c43eedc96d3sewardj 6407ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl < VexRegUpdAllregsAtEachInsn) { 6408ca2c3c75784d35d136fc7c952717cdee5063c193sewardj redundant_put_removal_BB ( bb, preciseMemExnsFn, pxControl ); 6409c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe } 64104345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 6411f0e431671cb877601c2f2e551f42246469b4ee62sewardj vex_printf("\n========= REDUNDANT PUT\n\n" ); 6412dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 6413f0e431671cb877601c2f2e551f42246469b4ee62sewardj } 6414044a215317abdd84dd7224a416595c43eedc96d3sewardj 64154345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj bb = cprop_BB ( bb ); 64164345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 641784be73746586afb2ea1f197907fd7271c8d1e2ffsewardj vex_printf("\n========= CPROPD\n\n" ); 6418dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 641984be73746586afb2ea1f197907fd7271c8d1e2ffsewardj } 64202963239357452b96dbe6de1b3f8b626ea3305780sewardj 642149651f4b59b1ab7e0e70cccd34001630eafbe957sewardj do_deadcode_BB ( bb ); 64224345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 642339e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj vex_printf("\n========= DEAD\n\n" ); 6424dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 642539e3f248ea24946bf856dd9c9baaa8cacb9a0e39sewardj } 64262963239357452b96dbe6de1b3f8b626ea3305780sewardj 6427b92307503d4fb9265136e182d10c42ebb9dd8272sewardj bb = spec_helpers_BB ( bb, specHelper ); 642849651f4b59b1ab7e0e70cccd34001630eafbe957sewardj do_deadcode_BB ( bb ); 64294345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 643084ff0657940e62f38e618ea18bac6f27ce0e741fsewardj vex_printf("\n========= SPECd \n\n" ); 6431dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 643284ff0657940e62f38e618ea18bac6f27ce0e741fsewardj } 643384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj 64344345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj return bb; 64354345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj} 64364345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6437695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6438695cff9303ef5dc8079117acfd632b44edb1f010sewardj/* Do some more expensive transformations on bb, which are aimed at 6439695cff9303ef5dc8079117acfd632b44edb1f010sewardj optimising as much as possible in the presence of GetI and PutI. */ 6440695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6441695cff9303ef5dc8079117acfd632b44edb1f010sewardjstatic 6442ca2c3c75784d35d136fc7c952717cdee5063c193sewardjIRSB* expensive_transformations( IRSB* bb, VexRegisterUpdates pxControl ) 6443695cff9303ef5dc8079117acfd632b44edb1f010sewardj{ 64442608c6946f80e733875aa4969c39740fcb012c17sewardj (void)do_cse_BB( bb, False/*!allowLoadsToBeCSEd*/ ); 6445695cff9303ef5dc8079117acfd632b44edb1f010sewardj collapse_AddSub_chains_BB( bb ); 64460821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj do_redundant_GetI_elimination( bb ); 6447ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl < VexRegUpdAllregsAtEachInsn) { 6448ca2c3c75784d35d136fc7c952717cdee5063c193sewardj do_redundant_PutI_elimination( bb, pxControl ); 6449c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe } 645049651f4b59b1ab7e0e70cccd34001630eafbe957sewardj do_deadcode_BB( bb ); 6451b92307503d4fb9265136e182d10c42ebb9dd8272sewardj return bb; 6452695cff9303ef5dc8079117acfd632b44edb1f010sewardj} 6453695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6454695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6455b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj/* Scan a flattened BB to look for signs that more expensive 6456b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj optimisations might be useful: 6457b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj - find out if there are any GetIs and PutIs 6458b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj - find out if there are any floating or vector-typed temporaries 6459b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj*/ 6460695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6461b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic void considerExpensives ( /*OUT*/Bool* hasGetIorPutI, 6462b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj /*OUT*/Bool* hasVorFtemps, 6463dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB* bb ) 64644345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj{ 6465e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj Int i, j; 6466e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRStmt* st; 64674345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj IRDirty* d; 6468e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj IRCAS* cas; 64694345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6470b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj *hasGetIorPutI = False; 6471b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj *hasVorFtemps = False; 6472b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 64734345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj for (i = 0; i < bb->stmts_used; i++) { 64744345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj st = bb->stmts[i]; 64754345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj switch (st->tag) { 64765a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj case Ist_AbiHint: 64775a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj vassert(isIRAtom(st->Ist.AbiHint.base)); 6478478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj vassert(isIRAtom(st->Ist.AbiHint.nia)); 64795a9ffab9150b7cca31d44d48da998d011bbe8e6asewardj break; 64804345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj case Ist_PutI: 6481b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj *hasGetIorPutI = True; 6482b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj break; 6483dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj case Ist_WrTmp: 6484dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj if (st->Ist.WrTmp.data->tag == Iex_GetI) 6485b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj *hasGetIorPutI = True; 6486dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj switch (typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp)) { 6487b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Ity_I1: case Ity_I8: case Ity_I16: 6488b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj case Ity_I32: case Ity_I64: case Ity_I128: 6489b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj break; 64903738bfcea70600334c830de5421adc0204890c95sewardj case Ity_F16: case Ity_F32: case Ity_F64: case Ity_F128: 6491c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj case Ity_V128: case Ity_V256: 6492b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj *hasVorFtemps = True; 6493c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj break; 6494c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj case Ity_D32: case Ity_D64: case Ity_D128: 6495c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj *hasVorFtemps = True; 6496b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj break; 6497b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj default: 6498b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj goto bad; 6499b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 65004345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj break; 65014345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj case Ist_Put: 6502496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Put.data)); 65034345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj break; 6504af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj case Ist_Store: 6505af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.addr)); 6506af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj vassert(isIRAtom(st->Ist.Store.data)); 65074345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj break; 6508cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_StoreG: { 6509cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRStoreG* sg = st->Ist.StoreG.details; 6510cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->addr)); 6511cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->data)); 6512cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(sg->guard)); 6513cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 6514cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 6515cfe046e178666280b87da998b1b52ecda03ecd89sewardj case Ist_LoadG: { 6516cfe046e178666280b87da998b1b52ecda03ecd89sewardj IRLoadG* lg = st->Ist.LoadG.details; 6517cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->addr)); 6518cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->alt)); 6519cfe046e178666280b87da998b1b52ecda03ecd89sewardj vassert(isIRAtom(lg->guard)); 6520cfe046e178666280b87da998b1b52ecda03ecd89sewardj break; 6521cfe046e178666280b87da998b1b52ecda03ecd89sewardj } 6522e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj case Ist_CAS: 6523e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj cas = st->Ist.CAS.details; 6524e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->addr)); 6525e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(cas->expdHi == NULL || isIRAtom(cas->expdHi)); 6526e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->expdLo)); 6527e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(cas->dataHi == NULL || isIRAtom(cas->dataHi)); 6528e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj vassert(isIRAtom(cas->dataLo)); 6529e9d8a26b690c2561ac54ab0cd6ad83ecbadcbe76sewardj break; 6530e768e92e054cde495849a5c842a477d287677f78sewardj case Ist_LLSC: 6531e768e92e054cde495849a5c842a477d287677f78sewardj vassert(isIRAtom(st->Ist.LLSC.addr)); 6532e768e92e054cde495849a5c842a477d287677f78sewardj if (st->Ist.LLSC.storedata) 6533e768e92e054cde495849a5c842a477d287677f78sewardj vassert(isIRAtom(st->Ist.LLSC.storedata)); 6534e768e92e054cde495849a5c842a477d287677f78sewardj break; 65354345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj case Ist_Dirty: 65364345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj d = st->Ist.Dirty.details; 6537496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(d->guard)); 653874142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj for (j = 0; d->args[j]; j++) { 653974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj IRExpr* arg = d->args[j]; 6540ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg))) 654174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj vassert(isIRAtom(arg)); 654274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj } 65434345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (d->mFx != Ifx_None) 6544496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(d->mAddr)); 65454345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj break; 6546d2445f60726580b450eca68ab40c568f9df338e2sewardj case Ist_NoOp: 6547f168931fd8a8256c020c9b90d5f2e05f1e6c48c7sewardj case Ist_IMark: 6548c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj case Ist_MBE: 65493e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj break; 65503e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj case Ist_Exit: 6551496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj vassert(isIRAtom(st->Ist.Exit.guard)); 65523e83893fff6c7bbc955d4529cd922df4ed9b23cdsewardj break; 65534345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj default: 6554b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj bad: 65554345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj ppIRStmt(st); 6556e768e92e054cde495849a5c842a477d287677f78sewardj vpanic("considerExpensives"); 65574345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj } 65584345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj } 65594345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj} 65604345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 65614345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6562695cff9303ef5dc8079117acfd632b44edb1f010sewardj/* ---------------- The main iropt entry point. ---------------- */ 6563695cff9303ef5dc8079117acfd632b44edb1f010sewardj 65644345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj/* exported from this file */ 6565695cff9303ef5dc8079117acfd632b44edb1f010sewardj/* Rules of the game: 6566695cff9303ef5dc8079117acfd632b44edb1f010sewardj 6567695cff9303ef5dc8079117acfd632b44edb1f010sewardj - IRExpr/IRStmt trees should be treated as immutable, as they 6568695cff9303ef5dc8079117acfd632b44edb1f010sewardj may get shared. So never change a field of such a tree node; 6569695cff9303ef5dc8079117acfd632b44edb1f010sewardj instead construct and return a new one if needed. 6570695cff9303ef5dc8079117acfd632b44edb1f010sewardj*/ 6571695cff9303ef5dc8079117acfd632b44edb1f010sewardj 65724345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6573be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardjIRSB* do_iropt_BB( 6574be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj IRSB* bb0, 65751ff4756e1731485e6bf3cd96717cd8398daec1f2florian IRExpr* (*specHelper) (const HChar*, IRExpr**, IRStmt**, Int), 6576ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 6577ca2c3c75784d35d136fc7c952717cdee5063c193sewardj VexRegisterUpdates pxControl, 6578d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian Addr guest_addr, 6579be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj VexArch guest_arch 6580be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj ) 65814345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj{ 65829d2e769a9368d2b22c32a4764a70e9da38769628sewardj static Int n_total = 0; 65839d2e769a9368d2b22c32a4764a70e9da38769628sewardj static Int n_expensive = 0; 65844345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6585b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj Bool hasGetIorPutI, hasVorFtemps; 6586dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj IRSB *bb, *bb2; 65878c2c10bcac223041c2d8f5e0a41a2c28261dab0fsewardj 65884345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj n_total++; 65894345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 65904345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj /* First flatten the block out, since all other 65914345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj phases assume flat code. */ 65924345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 65934345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj bb = flatten_BB ( bb0 ); 65944345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 65954345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj if (iropt_verbose) { 65964345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj vex_printf("\n========= FLAT\n\n" ); 6597dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj ppIRSB(bb); 65984345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj } 65994345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 66000821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj /* If at level 0, stop now. */ 66010821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj if (vex_control.iropt_level <= 0) return bb; 66020821053bd75b33ab1f5a7d84cdb1550d2b066a8fsewardj 6603695cff9303ef5dc8079117acfd632b44edb1f010sewardj /* Now do a preliminary cleanup pass, and figure out if we also 6604695cff9303ef5dc8079117acfd632b44edb1f010sewardj need to do 'expensive' optimisations. Expensive optimisations 6605695cff9303ef5dc8079117acfd632b44edb1f010sewardj are deemed necessary if the block contains any GetIs or PutIs. 6606695cff9303ef5dc8079117acfd632b44edb1f010sewardj If needed, do expensive transformations and then another cheap 6607695cff9303ef5dc8079117acfd632b44edb1f010sewardj cleanup pass. */ 66084345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj 6609ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = cheap_transformations( bb, specHelper, preciseMemExnsFn, pxControl ); 661039555aa10bcda6a509563698398ea2d5fdd45fdbsewardj 6611be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj if (guest_arch == VexArchARM) { 6612be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj /* Translating Thumb2 code produces a lot of chaff. We have to 6613be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj work extra hard to get rid of it. */ 6614be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj bb = cprop_BB(bb); 6615be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj bb = spec_helpers_BB ( bb, specHelper ); 6616ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl < VexRegUpdAllregsAtEachInsn) { 6617ca2c3c75784d35d136fc7c952717cdee5063c193sewardj redundant_put_removal_BB ( bb, preciseMemExnsFn, pxControl ); 6618c8e2f983c84affb3cbe4cebee1516aedaf944f79philippe } 66192608c6946f80e733875aa4969c39740fcb012c17sewardj do_cse_BB( bb, False/*!allowLoadsToBeCSEd*/ ); 6620be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj do_deadcode_BB( bb ); 6621be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj } 6622be9179130bdfb61d0e03ecb32eced8dd5c7bfc74sewardj 662308613749b639323cc7582c1bbe56c6e21c69774fsewardj if (vex_control.iropt_level > 1) { 6624b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 6625b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj /* Peer at what we have, to decide how much more effort to throw 6626b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj at it. */ 6627b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj considerExpensives( &hasGetIorPutI, &hasVorFtemps, bb ); 6628b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 66299b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (hasVorFtemps && !hasGetIorPutI) { 6630b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj /* If any evidence of FP or Vector activity, CSE, as that 6631b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj tends to mop up all manner of lardy code to do with 66329b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj rounding modes. Don't bother if hasGetIorPutI since that 66339b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj case leads into the expensive transformations, which do 66349b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj CSE anyway. */ 66352608c6946f80e733875aa4969c39740fcb012c17sewardj (void)do_cse_BB( bb, False/*!allowLoadsToBeCSEd*/ ); 6636b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj do_deadcode_BB( bb ); 6637b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj } 6638b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj 6639b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (hasGetIorPutI) { 66409b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj Bool cses; 664139555aa10bcda6a509563698398ea2d5fdd45fdbsewardj n_expensive++; 664239555aa10bcda6a509563698398ea2d5fdd45fdbsewardj if (DEBUG_IROPT) 664339555aa10bcda6a509563698398ea2d5fdd45fdbsewardj vex_printf("***** EXPENSIVE %d %d\n", n_total, n_expensive); 6644ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = expensive_transformations( bb, pxControl ); 6645ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = cheap_transformations( bb, specHelper, 6646ca2c3c75784d35d136fc7c952717cdee5063c193sewardj preciseMemExnsFn, pxControl ); 66479b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj /* Potentially common up GetIs */ 66482608c6946f80e733875aa4969c39740fcb012c17sewardj cses = do_cse_BB( bb, False/*!allowLoadsToBeCSEd*/ ); 66499b0cc5856f608e2779f8e1855d224299c7cbe8d4sewardj if (cses) 6650ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = cheap_transformations( bb, specHelper, 6651ca2c3c75784d35d136fc7c952717cdee5063c193sewardj preciseMemExnsFn, pxControl ); 6652695cff9303ef5dc8079117acfd632b44edb1f010sewardj } 665339555aa10bcda6a509563698398ea2d5fdd45fdbsewardj 665416caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /////////////////////////////////////////////////////////// 665516caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // BEGIN MSVC optimised code transformation hacks 665616caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj if (0) 665716caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj bb = do_MSVC_HACKS(bb); 665816caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj // END MSVC optimised code transformation hacks 665916caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj /////////////////////////////////////////////////////////// 666016caded3d5c2be18c9f4ee0f1d957d23d2b6bbccsewardj 666139555aa10bcda6a509563698398ea2d5fdd45fdbsewardj /* Now have a go at unrolling simple (single-BB) loops. If 666239555aa10bcda6a509563698398ea2d5fdd45fdbsewardj successful, clean up the results as much as possible. */ 666339555aa10bcda6a509563698398ea2d5fdd45fdbsewardj 666439555aa10bcda6a509563698398ea2d5fdd45fdbsewardj bb2 = maybe_loop_unroll_BB( bb, guest_addr ); 666539555aa10bcda6a509563698398ea2d5fdd45fdbsewardj if (bb2) { 6666ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = cheap_transformations( bb2, specHelper, 6667ca2c3c75784d35d136fc7c952717cdee5063c193sewardj preciseMemExnsFn, pxControl ); 6668b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj if (hasGetIorPutI) { 6669ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = expensive_transformations( bb, pxControl ); 6670ca2c3c75784d35d136fc7c952717cdee5063c193sewardj bb = cheap_transformations( bb, specHelper, 6671ca2c3c75784d35d136fc7c952717cdee5063c193sewardj preciseMemExnsFn, pxControl ); 667239555aa10bcda6a509563698398ea2d5fdd45fdbsewardj } else { 667339555aa10bcda6a509563698398ea2d5fdd45fdbsewardj /* at least do CSE and dead code removal */ 66742608c6946f80e733875aa4969c39740fcb012c17sewardj do_cse_BB( bb, False/*!allowLoadsToBeCSEd*/ ); 667549651f4b59b1ab7e0e70cccd34001630eafbe957sewardj do_deadcode_BB( bb ); 667639555aa10bcda6a509563698398ea2d5fdd45fdbsewardj } 667739555aa10bcda6a509563698398ea2d5fdd45fdbsewardj if (0) vex_printf("vex iropt: unrolled a loop\n"); 667839555aa10bcda6a509563698398ea2d5fdd45fdbsewardj } 667939555aa10bcda6a509563698398ea2d5fdd45fdbsewardj 66802963239357452b96dbe6de1b3f8b626ea3305780sewardj } 66812963239357452b96dbe6de1b3f8b626ea3305780sewardj 66824345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj return bb; 6683edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj} 6684edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj 6685edf4d69c8477cad95851d0f6ccf91ab323e5a446sewardj 6686a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 6687cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end ir_opt.c ---*/ 6688a1a370fcecc7b4ed6989498b4fc0166558758bfdsewardj/*---------------------------------------------------------------*/ 6689