void IEC::updateIecLines() { bool signals_changed; bool atn_edge; // Update port lines signals_changed = _updateIecLines(&atn_edge); // Check if ATN edge occurred if (atn_edge) { drive->simulateAtnInterrupt(); } if (signals_changed) { if (busActivity == 0) { // Bus activity detected drive->c64->putMessage(MSG_VC1541_DATA, 1); drive->c64->setWarp(drive->c64->getAlwaysWarp() || drive->c64->getWarpLoad()); } busActivity = 30; } if (signals_changed && tracingEnabled()) { dumpTrace(); } }
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) { auto finishPass = [&](const char* msg) { dumpTrace(6, unit, folly::format("after {}", msg).str().c_str()); assert(checkCfg(unit)); assert(checkTmpsSpanningCalls(unit)); if (debug) { forEachInst(rpoSortCfg(unit), assertOperandTypes); } }; auto doPass = [&](void (*fn)(IRUnit&), const char* msg) { fn(unit); finishPass(msg); }; auto dce = [&](const char* which) { if (!RuntimeOption::EvalHHIRDeadCodeElim) return; eliminateDeadCode(unit); finishPass(folly::format("{} DCE", which).str().c_str()); }; if (RuntimeOption::EvalHHIRRelaxGuards) { auto const simpleRelax = kind == TransProfile; auto changed = relaxGuards(unit, *irBuilder.guards(), simpleRelax); if (changed) finishPass("guard relaxation"); } if (RuntimeOption::EvalHHIRRefcountOpts) { optimizeRefcounts(unit); finishPass("refcount opts"); } dce("initial"); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(optimizePredictions, "prediction opts"); } if (RuntimeOption::EvalHHIRExtraOptPass && (RuntimeOption::EvalHHIRCse || RuntimeOption::EvalHHIRSimplification)) { irBuilder.reoptimize(); finishPass("reoptimize"); // Cleanup any dead code left around by CSE/Simplification // Ideally, this would be controlled by a flag returned // by optimzeTrace indicating whether DCE is necessary dce("reoptimize"); } if (RuntimeOption::EvalHHIRJumpOpts) { doPass(optimizeJumps, "jumpopts"); dce("jump opts"); } if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(insertAsserts, "RefCnt asserts"); } }
void optimizeTrace(IRTrace* trace, TraceBuilder& traceBuilder) { auto& irFactory = traceBuilder.factory(); auto finishPass = [&](const char* msg) { dumpTrace(6, trace, folly::format("after {}", msg).str().c_str()); assert(checkCfg(trace, irFactory)); assert(checkTmpsSpanningCalls(trace, irFactory)); if (debug) forEachTraceInst(trace, assertOperandTypes); }; auto doPass = [&](void (*fn)(IRTrace*, IRFactory&), const char* msg) { fn(trace, irFactory); finishPass(msg); }; auto dce = [&](const char* which) { if (!RuntimeOption::EvalHHIRDeadCodeElim) return; eliminateDeadCode(trace, irFactory); finishPass(folly::format("{} DCE", which).str().c_str()); }; if (RuntimeOption::EvalHHIRRelaxGuards) { auto changed = relaxGuards(trace, irFactory, *traceBuilder.guards()); if (changed) finishPass("guard relaxation"); } dce("initial"); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(optimizePredictions, "prediction opts"); } if (RuntimeOption::EvalHHIRExtraOptPass && (RuntimeOption::EvalHHIRCse || RuntimeOption::EvalHHIRSimplification)) { traceBuilder.reoptimize(); finishPass("reoptimize"); // Cleanup any dead code left around by CSE/Simplification // Ideally, this would be controlled by a flag returned // by optimzeTrace indicating whether DCE is necessary dce("reoptimize"); } if (RuntimeOption::EvalHHIRJumpOpts) { doPass(optimizeJumps, "jumpopts"); dce("jump opts"); } if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(insertAsserts, "RefCnt asserts"); } }
void IEC::dumpState() { msg("IEC bus\n"); msg("-------\n"); msg("\n"); dumpTrace(); msg("\n"); msg("Drive connected : %s\n", driveConnected ? "yes" : "no"); msg(" old ATN : %d\n", oldAtnLine); msg(" old CLK : %d\n", oldClockLine); msg(" old DATA : %d\n", oldDataLine); msg("\n"); }
void genCode(CodeBlock& main, CodeBlock& stubs, IRUnit& unit, std::vector<TransBCMapping>* bcMap, JIT::MCGenerator* mcg, const RegAllocInfo& regs) { Timer _t(Timer::codeGen); if (dumpIREnabled()) { AsmInfo ai(unit); genCodeImpl(main, stubs, unit, bcMap, mcg, regs, &ai); dumpTrace(kCodeGenLevel, unit, " after code gen ", ®s, &ai); } else { genCodeImpl(main, stubs, unit, bcMap, mcg, regs, nullptr); } }
int main(int argc, char **argv) { bool isRoot = (getuid() == 0); if (argc == 2 && 0 == strcmp(argv[1], "--help")) { showHelp(argv[0]); exit(0); } for (;;) { int ret; ret = getopt(argc, argv, "b:gcidflst:wz"); if (ret < 0) { break; } switch(ret) { case 'g': if (!isRoot) { fprintf(stderr, "error: tracing GPU power state requires root privileges\n"); exit(1); } g_traceGpuPower = true; break; case 'b': g_traceBufferSizeKB = atoi(optarg); break; case 'c': g_traceOverwrite = true; break; case 'i': g_traceCpuIdle = true; break; case 'l': g_traceGovernorLoad = true; break; case 'd': if (!isRoot) { fprintf(stderr, "error: tracing disk activity requires root privileges\n"); exit(1); } g_traceDisk = true; break; case 'f': g_traceCpuFrequency = true; break; case 's': g_traceSchedSwitch = true; break; case 't': g_traceDurationSeconds = atoi(optarg); break; case 'w': if (!isRoot) { fprintf(stderr, "error: tracing kernel work queues requires root privileges\n"); exit(1); } g_traceWorkqueue = true; break; case 'z': g_compress = true; break; default: fprintf(stderr, "\n"); showHelp(argv[0]); exit(-1); break; } } registerSigHandler(); bool ok = startTrace(isRoot); if (ok) { printf("capturing trace..."); fflush(stdout); // We clear the trace after starting it because tracing gets enabled for // each CPU individually in the kernel. Having the beginning of the trace // contain entries from only one CPU can cause "begin" entries without a // matching "end" entry to show up if a task gets migrated from one CPU to // another. ok = clearTrace(); if (ok) { // Sleep to allow the trace to be captured. struct timespec timeLeft; timeLeft.tv_sec = g_traceDurationSeconds; timeLeft.tv_nsec = 0; do { if (g_traceAborted) { break; } } while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR); } } // Stop the trace and restore the default settings. stopTrace(isRoot); if (ok) { if (!g_traceAborted) { printf(" done\nTRACE:\n"); fflush(stdout); dumpTrace(); } else { printf("\ntrace aborted.\n"); fflush(stdout); } clearTrace(); } else { fprintf(stderr, "unable to start tracing\n"); } // Reset the trace buffer size to 1. setTraceBufferSizeKB(1); return g_traceAborted ? 1 : 0; }
/* * ======== smain ======== */ Int smain(Int argc, String argv[]) { Char newTraceMask[MAXTRACESTRING]; Server_Handle server = NULL; Bool finished = FALSE; Uns mode = PULLTRACE; Server_Status status; Int traceToken; String mask; Uns rate; /* interpret PULLTRACE mode args */ if (argc == 3) { rate = atoi(argv[1]); mask = argv[2]; } /* else, if no args, set mode to TRACEUTIL */ else if (argc == 1) { mode = TRACEUTIL; } /* else, show usage */ else { fprintf(stderr, usage, argv[0]); goto done; } /* reset, load, and start DSP Engine */ if ((engine = Engine_open(engineName, NULL, NULL)) == NULL) { fprintf(stderr, "Error: can't open engine %s!\n", engineName); goto done; } /* setup file descriptor mask for checking for user key input */ FD_ZERO(&fdMask); FD_SET(STDIN_FILENO, &fdMask); /* if standard output mode... */ if (mode == PULLTRACE) { printf("Trace polling rate: %d msec\n", rate); rate *= 1000; printf("DSP trace mask: %s\n", mask); /* get server handle */ server = Engine_getServer(engine); if (server == NULL) { fprintf(stderr, "Error: can't get server handle!\n"); goto closeEngine; } /* connect for server trace data */ status = Server_connectTrace(server, &traceToken); if (status == Server_EINUSE) { fprintf(stderr, "Error: server trace already in use by another process!\n"); goto closeEngine; } else if (status != Server_EOK) { fprintf(stderr, "Error: server connect failed, status = 0x%x!\n", status); goto closeEngine; } /* server trace mask */ status = Server_setTrace(server, mask); if (status != (Int) Engine_EOK) { fprintf(stderr, "Error: unable to set trace mask, status = 0x%x!\n", status); goto closeEngine; } printf("Hit <Enter> to exit, or, new trace mask and then <Enter>...\n"); while (finished == FALSE) { dumpTrace(server); usleep(rate); if (checkInput(newTraceMask) == TRUE) { if (strlen(newTraceMask) == 0) { finished = TRUE; } else { printf("setting new trace mask: %s\n", newTraceMask); status = Server_setTrace(server, newTraceMask); if (status != (Int) Engine_EOK) { fprintf(stderr, "Error updating trace mask, status = 0x%x!\n", status); } } } }; /* discconnect from server trace data */ status = Server_disconnectTrace(server, traceToken); if (status != Server_EOK) { fprintf(stderr, "Error: unable to disconnect from server trace, status = 0x%x!\n", status); } } /* else, startup TraceUtil to retrieve trace/LOG data and write to files */ else { TraceUtil_start(engineName); printf("Started TraceUtil thread\nHit <Enter> to exit...\n"); getchar(); TraceUtil_stop(); } printf("Done.\n"); closeEngine: /* close the engine */ if (engine) { Engine_close(engine); } done: return (0); }
void optimize(IRUnit& unit, IRBuilder& irBuilder, TransKind kind) { Timer _t(Timer::optimize); auto finishPass = [&](const char* msg) { dumpTrace(6, unit, folly::format("after {}", msg).str().c_str()); assert(checkCfg(unit)); assert(checkTmpsSpanningCalls(unit)); if (debug) { forEachInst(rpoSortCfg(unit), assertOperandTypes); } }; auto doPass = [&](void (*fn)(IRUnit&), const char* msg) { fn(unit); finishPass(msg); }; auto dce = [&](const char* which) { if (!RuntimeOption::EvalHHIRDeadCodeElim) return; eliminateDeadCode(unit); finishPass(folly::format("{} DCE", which).str().c_str()); }; if (RuntimeOption::EvalHHIRRelaxGuards) { /* * In TransProfile mode, we can only relax the guards in tracelet * region mode. If the region came from analyze() and we relax the * guards here, then the RegionDesc's TypePreds in ProfData won't * accurately reflect the generated guards. This can result in a * TransOptimze region to be formed with types that are incompatible, * e.g.: * B1: TypePred: Loc0: Bool // but this gets relaxed to Uncounted * PostCond: Loc0: Uncounted // post-conds are accurate * B2: TypePred: Loc0: Int // this will always fail */ const bool relax = kind != TransProfile || RuntimeOption::EvalJitRegionSelector == "tracelet"; if (relax) { Timer _t(Timer::optimize_relaxGuards); const bool simple = kind == TransProfile && RuntimeOption::EvalJitRegionSelector == "tracelet"; auto changed = relaxGuards(unit, *irBuilder.guards(), simple); if (changed) finishPass("guard relaxation"); } } if (RuntimeOption::EvalHHIRRefcountOpts) { optimizeRefcounts(unit, FrameState{unit, unit.entry()->front().marker()}); finishPass("refcount opts"); } dce("initial"); if (RuntimeOption::EvalHHIRPredictionOpts) { doPass(optimizePredictions, "prediction opts"); } if (RuntimeOption::EvalHHIRExtraOptPass && (RuntimeOption::EvalHHIRCse || RuntimeOption::EvalHHIRSimplification)) { irBuilder.reoptimize(); finishPass("reoptimize"); // Cleanup any dead code left around by CSE/Simplification // Ideally, this would be controlled by a flag returned // by optimizeTrace indicating whether DCE is necessary dce("reoptimize"); } if (RuntimeOption::EvalHHIRJumpOpts) { doPass(optimizeJumps, "jumpopts"); dce("jump opts"); } if (RuntimeOption::EvalHHIRGenerateAsserts) { doPass(insertAsserts, "RefCnt asserts"); } }