1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2009 Nicolai Haehnle. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_dataflow.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct updatemask_state { 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char Output[RC_REGISTER_MAX_INDEX]; 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char Temporary[RC_REGISTER_MAX_INDEX]; 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char Address; 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char Special[RC_NUM_SPECIAL_REGISTERS]; 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct instruction_state { 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char WriteMask:4; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char WriteALUResult:1; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char SrcReg[3]; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct loopinfo { 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state * Breaks; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int BreakCount; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int BreaksReserved; 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct branchinfo { 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int HaveElse:1; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state StoreEndif; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state StoreElse; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct deadcode_state { 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * C; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct instruction_state * Instructions; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state R; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct branchinfo * BranchStack; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int BranchStackSize; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int BranchStackReserved; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct loopinfo * LoopStack; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int LoopStackSize; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int LoopStackReserved; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void or_updatemasks( 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state * dst, 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state * a, 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct updatemask_state * b) 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int i = 0; i < RC_REGISTER_MAX_INDEX; ++i) { 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Output[i] = a->Output[i] | b->Output[i]; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Temporary[i] = a->Temporary[i] | b->Temporary[i]; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int i = 0; i < RC_NUM_SPECIAL_REGISTERS; ++i) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Special[i] = a->Special[i] | b->Special[i]; 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Address = a->Address | b->Address; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void push_break(struct deadcode_state *s) 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct loopinfo * loop = &s->LoopStack[s->LoopStackSize - 1]; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_array_reserve(&s->C->Pool, struct updatemask_state, 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop->Breaks, loop->BreakCount, loop->BreaksReserved, 1); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&loop->Breaks[loop->BreakCount++], &s->R, sizeof(s->R)); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void push_loop(struct deadcode_state * s) 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_array_reserve(&s->C->Pool, struct loopinfo, s->LoopStack, 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->LoopStackSize, s->LoopStackReserved, 1); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&s->LoopStack[s->LoopStackSize++], 0, sizeof(struct loopinfo)); 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void push_branch(struct deadcode_state * s) 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct branchinfo * branch; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack, 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->BranchStackSize, s->BranchStackReserved, 1); 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branch = &s->BranchStack[s->BranchStackSize++]; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branch->HaveElse = 0; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&branch->StoreEndif, &s->R, sizeof(s->R)); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned char * get_used_ptr(struct deadcode_state *s, rc_register_file file, unsigned int index) 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == RC_FILE_OUTPUT || file == RC_FILE_TEMPORARY) { 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (index >= RC_REGISTER_MAX_INDEX) { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(s->C, "%s: index %i is out of bounds for file %i\n", __FUNCTION__, index, file); 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == RC_FILE_OUTPUT) 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &s->R.Output[index]; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &s->R.Temporary[index]; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (file == RC_FILE_ADDRESS) { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &s->R.Address; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (file == RC_FILE_SPECIAL) { 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (index >= RC_NUM_SPECIAL_REGISTERS) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(s->C, "%s: special file index %i out of bounds\n", __FUNCTION__, index); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &s->R.Special[index]; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void mark_used(struct deadcode_state * s, rc_register_file file, unsigned int index, unsigned int mask) 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char * pused = get_used_ptr(s, file, index); 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pused) 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pused |= mask; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void update_instruction(struct deadcode_state * s, struct rc_instruction * inst) 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct instruction_state * insts = &s->Instructions[inst->IP]; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int usedmask = 0; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int srcmasks[3]; 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg) { 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char * pused = get_used_ptr(s, inst->U.I.DstReg.File, inst->U.I.DstReg.Index); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pused) { 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usedmask = *pused & inst->U.I.DstReg.WriteMask; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pused &= ~usedmask; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insts->WriteMask |= usedmask; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.WriteALUResult) { 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned char * pused = get_used_ptr(s, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT); 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pused && *pused) { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.WriteALUResult == RC_ALURESULT_X) 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usedmask |= RC_MASK_X; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (inst->U.I.WriteALUResult == RC_ALURESULT_W) 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usedmask |= RC_MASK_W; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pused = 0; 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insts->WriteALUResult = 1; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_compute_sources_for_writemask(inst, usedmask, srcmasks); 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int refmask = 0; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int newsrcmask = srcmasks[src] & ~insts->SrcReg[src]; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insts->SrcReg[src] |= newsrcmask; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int chan = 0; chan < 4; ++chan) { 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (GET_BIT(newsrcmask, chan)) 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmask |= 1 << GET_SWZ(inst->U.I.SrcReg[src].Swizzle, chan); 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get rid of spurious bits from ZERO, ONE, etc. swizzles */ 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org refmask &= RC_MASK_XYZW; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!refmask) 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_used(s, inst->U.I.SrcReg[src].File, inst->U.I.SrcReg[src].Index, refmask); 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[src].RelAddr) 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X); 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void mark_output_use(void * data, unsigned int index, unsigned int mask) 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct deadcode_state * s = data; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_used(s, RC_FILE_OUTPUT, index, mask); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_dataflow_deadcode(struct radeon_compiler * c, void *user) 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct deadcode_state s; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int nr_instructions; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_dataflow_mark_outputs_fn dce = (rc_dataflow_mark_outputs_fn)user; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int ip; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&s, 0, sizeof(s)); 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.C = c; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nr_instructions = rc_recompute_ips(c); 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.Instructions = memory_pool_malloc(&c->Pool, sizeof(struct instruction_state)*nr_instructions); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(s.Instructions, 0, sizeof(struct instruction_state)*nr_instructions); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dce(c, &s, &mark_output_use); 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(struct rc_instruction * inst = c->Program.Instructions.Prev; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst != &c->Program.Instructions; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = inst->Prev) { 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(opcode->Opcode){ 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Mark all sources in the loop body as used before doing 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * normal deadcode analysis. This is probably not optimal. 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_ENDLOOP: 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int endloops = 1; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *ptr; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ptr = inst->Prev; endloops > 0; ptr = ptr->Prev){ 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = rc_get_opcode_info(ptr->U.I.Opcode); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){ 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endloops--; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(ptr->U.I.Opcode == RC_OPCODE_ENDLOOP){ 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endloops++; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(opcode->HasDstReg){ 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int src = 0; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int srcmasks[3]; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_compute_sources_for_writemask(ptr, 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr->U.I.DstReg.WriteMask, srcmasks); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(src=0; src < opcode->NumSrcRegs; src++){ 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mark_used(&s, 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr->U.I.SrcReg[src].File, 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr->U.I.SrcReg[src].Index, 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcmasks[src]); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org push_loop(&s); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_BRK: 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org push_break(&s); 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_BGNLOOP: 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct loopinfo * loop = &s.LoopStack[s.LoopStackSize-1]; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < loop->BreakCount; i++) { 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org or_updatemasks(&s.R, &s.R, &loop->Breaks[i]); 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_CONT: 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_OPCODE_ENDIF: 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org push_branch(&s); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->IsFlowControl && s.BranchStackSize) { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1]; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->Opcode == RC_OPCODE_IF) { 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org or_updatemasks(&s.R, 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &s.R, 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif); 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.BranchStackSize--; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (opcode->Opcode == RC_OPCODE_ELSE) { 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (branch->HaveElse) { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__); 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&branch->StoreElse, &s.R, sizeof(s.R)); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&s.R, &branch->StoreEndif, sizeof(s.R)); 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org branch->HaveElse = 1; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org update_instruction(&s, inst); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ip = 0; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(struct rc_instruction * inst = c->Program.Instructions.Next; 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst != &c->Program.Instructions; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = inst->Next, ++ip) { 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int dead = 1; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int srcmasks[3]; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int usemask; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!opcode->HasDstReg) { 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dead = 0; 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask = s.Instructions[ip].WriteMask; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s.Instructions[ip].WriteMask) 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dead = 0; 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (s.Instructions[ip].WriteALUResult) 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dead = 0; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.WriteALUResult = RC_ALURESULT_NONE; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dead) { 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * todelete = inst; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = inst->Prev; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_remove_instruction(todelete); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usemask = s.Instructions[ip].WriteMask; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.WriteALUResult == RC_ALURESULT_X) 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usemask |= RC_MASK_X; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (inst->U.I.WriteALUResult == RC_ALURESULT_W) 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usemask |= RC_MASK_W; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_compute_sources_for_writemask(inst, usemask, srcmasks); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int src = 0; src < 3; ++src) { 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(unsigned int chan = 0; chan < 4; ++chan) { 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!GET_BIT(srcmasks[src], chan)) 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SET_SWZ(inst->U.I.SrcReg[src].Swizzle, chan, RC_SWIZZLE_UNUSED); 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_calculate_inputs_outputs(c); 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 360