inst_queue_impl.hh (11365:83c3e117464e) | inst_queue_impl.hh (12105:742d80361989) |
---|---|
1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 965 unchanged lines hidden (view full) --- 974 completed_inst->isWriteBarrier()) { 975 memDepUnit[completed_inst->threadNumber].completeBarrier(completed_inst); 976 } 977 978 for (int dest_reg_idx = 0; 979 dest_reg_idx < completed_inst->numDestRegs(); 980 dest_reg_idx++) 981 { | 1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating --- 965 unchanged lines hidden (view full) --- 974 completed_inst->isWriteBarrier()) { 975 memDepUnit[completed_inst->threadNumber].completeBarrier(completed_inst); 976 } 977 978 for (int dest_reg_idx = 0; 979 dest_reg_idx < completed_inst->numDestRegs(); 980 dest_reg_idx++) 981 { |
982 PhysRegIndex dest_reg = | 982 PhysRegIdPtr dest_reg = |
983 completed_inst->renamedDestRegIdx(dest_reg_idx); 984 985 // Special case of uniq or control registers. They are not 986 // handled by the IQ and thus have no dependency graph entry. | 983 completed_inst->renamedDestRegIdx(dest_reg_idx); 984 985 // Special case of uniq or control registers. They are not 986 // handled by the IQ and thus have no dependency graph entry. |
987 // @todo Figure out a cleaner way to handle this. 988 if (dest_reg >= numPhysRegs) { 989 DPRINTF(IQ, "dest_reg :%d, numPhysRegs: %d\n", dest_reg, 990 numPhysRegs); | 987 if (dest_reg->isFixedMapping()) { 988 DPRINTF(IQ, "Reg %d [%s] is part of a fix mapping, skipping\n", 989 dest_reg->regIdx, RegClassStrings[dest_reg->regClass]); |
991 continue; 992 } 993 | 990 continue; 991 } 992 |
994 DPRINTF(IQ, "Waking any dependents on register %i.\n", 995 (int) dest_reg); | 993 DPRINTF(IQ, "Waking any dependents on register %i (%s).\n", 994 dest_reg->regIdx, 995 RegClassStrings[dest_reg->regClass]); |
996 997 //Go through the dependency chain, marking the registers as 998 //ready within the waiting instructions. | 996 997 //Go through the dependency chain, marking the registers as 998 //ready within the waiting instructions. |
999 DynInstPtr dep_inst = dependGraph.pop(dest_reg); | 999 DynInstPtr dep_inst = dependGraph.pop(dest_reg->flatIdx); |
1000 1001 while (dep_inst) { 1002 DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] " 1003 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState()); 1004 1005 // Might want to give more information to the instruction 1006 // so that it knows which of its source registers is 1007 // ready. However that would mean that the dependency 1008 // graph entries would need to hold the src_reg_idx. 1009 dep_inst->markSrcRegReady(); 1010 1011 addIfReady(dep_inst); 1012 | 1000 1001 while (dep_inst) { 1002 DPRINTF(IQ, "Waking up a dependent instruction, [sn:%lli] " 1003 "PC %s.\n", dep_inst->seqNum, dep_inst->pcState()); 1004 1005 // Might want to give more information to the instruction 1006 // so that it knows which of its source registers is 1007 // ready. However that would mean that the dependency 1008 // graph entries would need to hold the src_reg_idx. 1009 dep_inst->markSrcRegReady(); 1010 1011 addIfReady(dep_inst); 1012 |
1013 dep_inst = dependGraph.pop(dest_reg); | 1013 dep_inst = dependGraph.pop(dest_reg->flatIdx); |
1014 1015 ++dependents; 1016 } 1017 1018 // Reset the head node now that all of its dependents have 1019 // been woken up. | 1014 1015 ++dependents; 1016 } 1017 1018 // Reset the head node now that all of its dependents have 1019 // been woken up. |
1020 assert(dependGraph.empty(dest_reg)); 1021 dependGraph.clearInst(dest_reg); | 1020 assert(dependGraph.empty(dest_reg->flatIdx)); 1021 dependGraph.clearInst(dest_reg->flatIdx); |
1022 1023 // Mark the scoreboard as having that register ready. | 1022 1023 // Mark the scoreboard as having that register ready. |
1024 regScoreboard[dest_reg] = true; | 1024 regScoreboard[dest_reg->flatIdx] = true; |
1025 } 1026 return dependents; 1027} 1028 1029template <class Impl> 1030void 1031InstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst) 1032{ --- 181 unchanged lines hidden (view full) --- 1214 !squashed_inst->isStoreConditional() && 1215 !squashed_inst->isMemBarrier() && 1216 !squashed_inst->isWriteBarrier())) { 1217 1218 for (int src_reg_idx = 0; 1219 src_reg_idx < squashed_inst->numSrcRegs(); 1220 src_reg_idx++) 1221 { | 1025 } 1026 return dependents; 1027} 1028 1029template <class Impl> 1030void 1031InstructionQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst) 1032{ --- 181 unchanged lines hidden (view full) --- 1214 !squashed_inst->isStoreConditional() && 1215 !squashed_inst->isMemBarrier() && 1216 !squashed_inst->isWriteBarrier())) { 1217 1218 for (int src_reg_idx = 0; 1219 src_reg_idx < squashed_inst->numSrcRegs(); 1220 src_reg_idx++) 1221 { |
1222 PhysRegIndex src_reg = | 1222 PhysRegIdPtr src_reg = |
1223 squashed_inst->renamedSrcRegIdx(src_reg_idx); 1224 1225 // Only remove it from the dependency graph if it 1226 // was placed there in the first place. 1227 1228 // Instead of doing a linked list traversal, we 1229 // can just remove these squashed instructions 1230 // either at issue time, or when the register is 1231 // overwritten. The only downside to this is it 1232 // leaves more room for error. 1233 1234 if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && | 1223 squashed_inst->renamedSrcRegIdx(src_reg_idx); 1224 1225 // Only remove it from the dependency graph if it 1226 // was placed there in the first place. 1227 1228 // Instead of doing a linked list traversal, we 1229 // can just remove these squashed instructions 1230 // either at issue time, or when the register is 1231 // overwritten. The only downside to this is it 1232 // leaves more room for error. 1233 1234 if (!squashed_inst->isReadySrcRegIdx(src_reg_idx) && |
1235 src_reg < numPhysRegs) { 1236 dependGraph.remove(src_reg, squashed_inst); | 1235 !src_reg->isFixedMapping()) { 1236 dependGraph.remove(src_reg->flatIdx, squashed_inst); |
1237 } 1238 1239 1240 ++iqSquashedOperandsExamined; 1241 } 1242 } else if (!squashed_inst->isStoreConditional() || 1243 !squashed_inst->isCompleted()) { 1244 NonSpecMapIt ns_inst_it = --- 50 unchanged lines hidden (view full) --- 1295 bool return_val = false; 1296 1297 for (int src_reg_idx = 0; 1298 src_reg_idx < total_src_regs; 1299 src_reg_idx++) 1300 { 1301 // Only add it to the dependency graph if it's not ready. 1302 if (!new_inst->isReadySrcRegIdx(src_reg_idx)) { | 1237 } 1238 1239 1240 ++iqSquashedOperandsExamined; 1241 } 1242 } else if (!squashed_inst->isStoreConditional() || 1243 !squashed_inst->isCompleted()) { 1244 NonSpecMapIt ns_inst_it = --- 50 unchanged lines hidden (view full) --- 1295 bool return_val = false; 1296 1297 for (int src_reg_idx = 0; 1298 src_reg_idx < total_src_regs; 1299 src_reg_idx++) 1300 { 1301 // Only add it to the dependency graph if it's not ready. 1302 if (!new_inst->isReadySrcRegIdx(src_reg_idx)) { |
1303 PhysRegIndex src_reg = new_inst->renamedSrcRegIdx(src_reg_idx); | 1303 PhysRegIdPtr src_reg = new_inst->renamedSrcRegIdx(src_reg_idx); |
1304 1305 // Check the IQ's scoreboard to make sure the register 1306 // hasn't become ready while the instruction was in flight 1307 // between stages. Only if it really isn't ready should 1308 // it be added to the dependency graph. | 1304 1305 // Check the IQ's scoreboard to make sure the register 1306 // hasn't become ready while the instruction was in flight 1307 // between stages. Only if it really isn't ready should 1308 // it be added to the dependency graph. |
1309 if (src_reg >= numPhysRegs) { | 1309 if (src_reg->isFixedMapping()) { |
1310 continue; | 1310 continue; |
1311 } else if (!regScoreboard[src_reg]) { 1312 DPRINTF(IQ, "Instruction PC %s has src reg %i that " | 1311 } else if (!regScoreboard[src_reg->flatIdx]) { 1312 DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " |
1313 "is being added to the dependency chain.\n", | 1313 "is being added to the dependency chain.\n", |
1314 new_inst->pcState(), src_reg); | 1314 new_inst->pcState(), src_reg->regIdx, 1315 RegClassStrings[src_reg->regClass]); |
1315 | 1316 |
1316 dependGraph.insert(src_reg, new_inst); | 1317 dependGraph.insert(src_reg->flatIdx, new_inst); |
1317 1318 // Change the return value to indicate that something 1319 // was added to the dependency graph. 1320 return_val = true; 1321 } else { | 1318 1319 // Change the return value to indicate that something 1320 // was added to the dependency graph. 1321 return_val = true; 1322 } else { |
1322 DPRINTF(IQ, "Instruction PC %s has src reg %i that " | 1323 DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " |
1323 "became ready before it reached the IQ.\n", | 1324 "became ready before it reached the IQ.\n", |
1324 new_inst->pcState(), src_reg); | 1325 new_inst->pcState(), src_reg->regIdx, 1326 RegClassStrings[src_reg->regClass]); |
1325 // Mark a register ready within the instruction. 1326 new_inst->markSrcRegReady(src_reg_idx); 1327 } 1328 } 1329 } 1330 1331 return return_val; 1332} --- 7 unchanged lines hidden (view full) --- 1340 // to the producing instruction will be placed in the head node of 1341 // the dependency links. 1342 int8_t total_dest_regs = new_inst->numDestRegs(); 1343 1344 for (int dest_reg_idx = 0; 1345 dest_reg_idx < total_dest_regs; 1346 dest_reg_idx++) 1347 { | 1327 // Mark a register ready within the instruction. 1328 new_inst->markSrcRegReady(src_reg_idx); 1329 } 1330 } 1331 } 1332 1333 return return_val; 1334} --- 7 unchanged lines hidden (view full) --- 1342 // to the producing instruction will be placed in the head node of 1343 // the dependency links. 1344 int8_t total_dest_regs = new_inst->numDestRegs(); 1345 1346 for (int dest_reg_idx = 0; 1347 dest_reg_idx < total_dest_regs; 1348 dest_reg_idx++) 1349 { |
1348 PhysRegIndex dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx); | 1350 PhysRegIdPtr dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx); |
1349 | 1351 |
1350 // Instructions that use the misc regs will have a reg number 1351 // higher than the normal physical registers. In this case these 1352 // registers are not renamed, and there is no need to track | 1352 // Some registers have fixed mapping, and there is no need to track |
1353 // dependencies as these instructions must be executed at commit. | 1353 // dependencies as these instructions must be executed at commit. |
1354 if (dest_reg >= numPhysRegs) { | 1354 if (dest_reg->isFixedMapping()) { |
1355 continue; 1356 } 1357 | 1355 continue; 1356 } 1357 |
1358 if (!dependGraph.empty(dest_reg)) { | 1358 if (!dependGraph.empty(dest_reg->flatIdx)) { |
1359 dependGraph.dump(); | 1359 dependGraph.dump(); |
1360 panic("Dependency graph %i not empty!", dest_reg); | 1360 panic("Dependency graph %i (%s) (flat: %i) not empty!", 1361 dest_reg->regIdx, RegClassStrings[dest_reg->regClass], 1362 dest_reg->flatIdx); |
1361 } 1362 | 1363 } 1364 |
1363 dependGraph.setInst(dest_reg, new_inst); | 1365 dependGraph.setInst(dest_reg->flatIdx, new_inst); |
1364 1365 // Mark the scoreboard to say it's not yet ready. | 1366 1367 // Mark the scoreboard to say it's not yet ready. |
1366 regScoreboard[dest_reg] = false; | 1368 regScoreboard[dest_reg->flatIdx] = false; |
1367 } 1368} 1369 1370template <class Impl> 1371void 1372InstructionQueue<Impl>::addIfReady(DynInstPtr &inst) 1373{ 1374 // If the instruction now has all of its source registers --- 200 unchanged lines hidden --- | 1369 } 1370} 1371 1372template <class Impl> 1373void 1374InstructionQueue<Impl>::addIfReady(DynInstPtr &inst) 1375{ 1376 // If the instruction now has all of its source registers --- 200 unchanged lines hidden --- |