// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool RecursionElimination::AnalyzeCalls() { // Scan all instructions and search for tail-recursive calls. bool hasTailCall = false; for(auto block = funct_->FirstBlock(); block; block = block->NextBlock()) { for(auto instr = block->FirstInstruction(); instr; instr = instr->NextInstruction()) { if(auto callInstr = instr->As<CallInstr>()) { TailCallInfo info; if(IsTailCall(callInstr, info)) { // We process it later. Mark the 'ret' instruction as visited. tailCalls_.Add(info); processedReturns_.Add(info.TailReturn, true); hasTailCall = true; } } else if(auto retInstr = instr->As<ReturnInstr>()) { // Add the 'ret' to the list if it isn't // part of a tail-call. if(processedReturns_.ContainsKey(retInstr) == false) { returnInstrs_.Add(retInstr); } } } } return hasTailCall; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void VariableAnalysis::AnayzeAggregateOperations(OperandVariableDict& opDict) { // We use a reverse-postorder walk that guarantees that we visit // all predecessors of a block before we visit that block. CFGInfo<Block, Function> cfgInfo(funct_, false /* edgeInfoNeeded */); auto& postorderList = cfgInfo.PostorderList(); for(int i = postorderList.Count() - 1; i >= 0; i--) { auto block = const_cast<Block*>(postorderList[i]); for(auto instr = block->FirstInstruction(); instr; instr = instr->NextInstruction()) { AnalyzeAggregatesInIntruction(instr, opDict); } } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AggregateCopyPropagation::RemovedDeadCopySetCalls() { // We count how many times each copy is used in the function. // All copies that are not used anymore can be removed, // allowing Dead Code Elimination to do it's job. List<int> copyCount(infoList_.Count()); for(int i = 0; i < infoList_.Count(); i++) { copyCount.Add(0); } // Scan all instructions in the function. for(auto block = funct_->FirstBlock(); block; block = block->NextBlock()) { for(auto instr = block->FirstInstruction(); instr; instr = instr->NextInstruction()) { // We check 'store', 'load' and 'call' instructions only, // because they're the ones that can access the copy. if(auto loadInstr = instr->As<LoadInstr>()) { VisitedDict visited; MarkUsedCopies(loadInstr->SourceOp(), copyCount, visited); } else if(auto storeInstr = instr->As<StoreInstr>()) { VisitedDict visited1; MarkUsedCopies(storeInstr->DestinationOp(), copyCount, visited1, true /* ignoreLocals */); VisitedDict visited2; MarkUsedCopies(storeInstr->SourceOp(), copyCount, visited2, true /* ignoreLocals */); } else if(auto callInstr = instr->As<CallInstr>()) { for(int i = 0; i < callInstr->ArgumentCount(); i++) { VisitedDict visited; MarkUsedCopies(callInstr->GetArgument(i), copyCount, visited); } } } } // Remove any copy that is definitely dead. for(int i = 0; i < copyCount.Count(); i++) { if((copyCount[i] - infoList_[i].Replacements) < 2) { infoList_[i].CopySetCall->RemoveFromBlock(true /* free */); } } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void AddressLowering::Execute(Function* function) { irGen_ = IRGenerator(function->ParentUnit()); // Process each instruction in the function. for(auto block = function->FirstBlock(); block; block = block->NextBlock()) { auto instr = block->FirstInstruction(); while(instr) { if(auto indexInstr = instr->As<IndexInstr>()) { instr = LowerIndex(indexInstr); } else if(auto addrInstr = instr->As<AddressInstr>()) { instr = LowerAddress(addrInstr); } else if(auto elemInstr = instr->As<ElementInstr>()) { instr = LowerElement(elemInstr); } else instr = instr->NextInstruction(); } } }
void bootstrap(char * entry, char * bootPkg, char * version) { char errorMsg[MAX_MSG_LEN]; defineExitProg(); defineDieProg(); // defineTrapProg(); // defineObjectProg(kmain); defineResumeProgs(); /* define the resume entry points */ ptrI mainThread = newThread(); processPo root = rootProcess(mainThread, bootPkg); // We create the root with a early death code - updated later switch (loadPackage(bootPkg, version, errorMsg, NumberOf(errorMsg), NULL)) { default: logMsg(logFile, "corrupt or no boot package found in %s:%s", bootPkg, errorMsg); lo_exit(EXIT_FAIL); return; case Eof: logMsg(logFile, "short boot package %s", bootPkg); lo_exit(EXIT_FAIL); return; case Ok: { ptrI prog = newProgramLbl(entry, 0); if (!IsProgram(prog)) { logMsg(logFile, "%U entry point not found", entry); lo_exit(EXIT_FAIL); } else { root->proc.PROG = ProgramOf(prog); /* this is where we establish the program */ root->proc.PC = FirstInstruction(root->proc.PROG); root->proc.thread = kmainThread; runGo(root); } } } }