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 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. |
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]); |
990 continue; 991 } 992 |
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. |
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 |
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. |
1020 assert(dependGraph.empty(dest_reg->flatIdx)); 1021 dependGraph.clearInst(dest_reg->flatIdx); |
1022 1023 // Mark the scoreboard as having that register ready. |
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 { |
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) && |
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)) { |
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. |
1309 if (src_reg->isFixedMapping()) { |
1310 continue; |
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", |
1314 new_inst->pcState(), src_reg->regIdx, 1315 RegClassStrings[src_reg->regClass]); |
1316 |
1317 dependGraph.insert(src_reg->flatIdx, new_inst); |
1318 1319 // Change the return value to indicate that something 1320 // was added to the dependency graph. 1321 return_val = true; 1322 } else { |
1323 DPRINTF(IQ, "Instruction PC %s has src reg %i (%s) that " |
1324 "became ready before it reached the IQ.\n", |
1325 new_inst->pcState(), src_reg->regIdx, 1326 RegClassStrings[src_reg->regClass]); |
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 { |
1350 PhysRegIdPtr dest_reg = new_inst->renamedDestRegIdx(dest_reg_idx); |
1351 |
1352 // Some registers have fixed mapping, and there is no need to track |
1353 // dependencies as these instructions must be executed at commit. |
1354 if (dest_reg->isFixedMapping()) { |
1355 continue; 1356 } 1357 |
1358 if (!dependGraph.empty(dest_reg->flatIdx)) { |
1359 dependGraph.dump(); |
1360 panic("Dependency graph %i (%s) (flat: %i) not empty!", 1361 dest_reg->regIdx, RegClassStrings[dest_reg->regClass], 1362 dest_reg->flatIdx); |
1363 } 1364 |
1365 dependGraph.setInst(dest_reg->flatIdx, new_inst); |
1366 1367 // Mark the scoreboard to say it's not yet ready. |
1368 regScoreboard[dest_reg->flatIdx] = false; |
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 --- |