Пример #1
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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;
}
Пример #2
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 */);
        }
    }
}
Пример #4
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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();
        }
    }
}
Пример #5
0
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);
      }
    }
  }
}