コード例 #1
0
bool PatmosSPMark::runOnMachineModule(const Module &M) {
  DEBUG( dbgs() <<
         "[Single-Path] Mark functions reachable from single-path roots\n");

  MMI = &getAnalysis<MachineModuleInfo>();
  assert(MMI);

  Worklist W;
  // initialize the worklist with machine functions that have either
  // sp-root or sp-reachable function attribute
  for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) {
    if (F->hasFnAttribute("sp-root") || F->hasFnAttribute("sp-reachable")) {
      // get the machine-level function
      MachineFunction *MF = MMI->getMachineFunction(F);
      assert( MF );
      PatmosMachineFunctionInfo *PMFI =
        MF->getInfo<PatmosMachineFunctionInfo>();
      PMFI->setSinglePath();
      NumSPTotal++; // bump STATISTIC
      W.push_back(MF);
    }
  }

  // process worklist
  while (!W.empty()) {
    MachineFunction *MF = W.front();
    W.pop_front();
    scanAndRewriteCalls(MF, W);
  }

  removeUncalledSPFunctions(M);

  // We either have rewritten calls or removed superfluous functions.
  return true;
}
コード例 #2
0
static CompilationResult compileImpl(
    VM& vm, CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationMode mode,
    unsigned osrEntryBytecodeIndex, const Operands<JSValue>& mustHandleValues,
    PassRefPtr<DeferredCompilationCallback> callback)
{
    SamplingRegion samplingRegion("DFG Compilation (Driver)");
    
    numCompilations++;
    
    ASSERT(codeBlock);
    ASSERT(codeBlock->alternative());
    ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
    ASSERT(!profiledDFGCodeBlock || profiledDFGCodeBlock->jitType() == JITCode::DFGJIT);
    
    if (logCompilationChanges(mode))
        dataLog("DFG(Driver) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n");
    
    // Make sure that any stubs that the DFG is going to use are initialized. We want to
    // make sure that all JIT code generation does finalization on the main thread.
    vm.getCTIStub(osrExitGenerationThunkGenerator);
    vm.getCTIStub(throwExceptionFromCallSlowPathGenerator);
    if (mode == DFGMode) {
        vm.getCTIStub(linkCallThunkGenerator);
        vm.getCTIStub(linkConstructThunkGenerator);
        vm.getCTIStub(linkClosureCallThunkGenerator);
        vm.getCTIStub(virtualCallThunkGenerator);
        vm.getCTIStub(virtualConstructThunkGenerator);
    } else {
        vm.getCTIStub(linkCallThatPreservesRegsThunkGenerator);
        vm.getCTIStub(linkConstructThatPreservesRegsThunkGenerator);
        vm.getCTIStub(linkClosureCallThatPreservesRegsThunkGenerator);
        vm.getCTIStub(virtualCallThatPreservesRegsThunkGenerator);
        vm.getCTIStub(virtualConstructThatPreservesRegsThunkGenerator);
    }
    
    if (CallEdgeLog::isEnabled())
        vm.ensureCallEdgeLog().processLog();

    if (vm.typeProfiler())
        vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Preparing for DFG compilation."));
    
    RefPtr<Plan> plan = adoptRef(
        new Plan(codeBlock, profiledDFGCodeBlock, mode, osrEntryBytecodeIndex, mustHandleValues));
    
    if (Options::enableConcurrentJIT()) {
        Worklist* worklist = ensureGlobalWorklistFor(mode);
        plan->callback = callback;
        if (logCompilationChanges(mode))
            dataLog("Deferring DFG compilation of ", *codeBlock, " with queue length ", worklist->queueLength(), ".\n");
        worklist->enqueue(plan);
        return CompilationDeferred;
    }
    
    plan->compileInThread(*vm.dfgState, 0);
    return plan->finalizeWithoutNotifyingCallback();
}
コード例 #3
0
void PatmosSPMark::scanAndRewriteCalls(MachineFunction *MF, Worklist &W) {
  for (MachineFunction::iterator MBB = MF->begin(), MBBE = MF->end();
                                 MBB != MBBE; ++MBB) {
    for( MachineBasicBlock::iterator MI = MBB->begin(),
                                     ME = MBB->getFirstTerminator();
                                     MI != ME; ++MI) {
      if (MI->isCall()) {
        MachineFunction *MF = getCallTargetMF(MI);
        if (!MF) {
          dbgs() << "[Single-Path] WARNING: Cannot rewrite call in "
                 << MBB->getParent()->getFunction()->getName()
                 << " (indirect call?)\n";
          continue;
        };

        const Function *Target = getCallTarget(MI);
        if (Target->getName() == "__udivsi3") {
          //DEBUG(dbgs() << "[Single-Path] skipping call to "
          //       << Target->getName() << "\n");
          //continue;
        }


        PatmosMachineFunctionInfo *PMFI =
          MF->getInfo<PatmosMachineFunctionInfo>();
        if (!PMFI->isSinglePath()) {
          // rewrite call to _sp variant
          rewriteCall(MI);
          // set _sp MF to single path in PMFI (MF has changed!)
          MachineFunction *MF = getCallTargetMF(MI);
          PatmosMachineFunctionInfo *PMFI =
            MF->getInfo<PatmosMachineFunctionInfo>();
          // we possibly have already marked the _sp variant as single-path
          // in an earlier call
          if (!PMFI->isSinglePath()) {
            PMFI->setSinglePath();
            // add the new single-path function to the worklist
            W.push_back(MF);

            NumSPTotal++; // bump STATISTIC
            NumSPMaybe++; // bump STATISTIC
          }
        }
      }
    }
  }
}
コード例 #4
0
void PatmosSPMark::scanAndRewriteCalls(MachineFunction *MF, Worklist &W) {
  DEBUG(dbgs() << "In function '" << MF->getName() << "':\n");
  for (MachineFunction::iterator MBB = MF->begin(), MBBE = MF->end();
                                 MBB != MBBE; ++MBB) {
    for( MachineBasicBlock::iterator MI = MBB->begin(),
                                     ME = MBB->getFirstTerminator();
                                     MI != ME; ++MI) {
      if (MI->isCall()) {
        MachineFunction *MF = getCallTargetMF(MI);
        if (!MF) {
          dbgs() << "[Single-Path] WARNING: Cannot rewrite call in "
                 << MBB->getParent()->getFunction()->getName()
                 << " (indirect call?)\n";
          continue;
        };

        const Function *Target = getCallTarget(MI);

        PatmosMachineFunctionInfo *PMFI =
          MF->getInfo<PatmosMachineFunctionInfo>();
        if (!PMFI->isSinglePath()) {
          // sp-reachable functions were already marked as single-path.
          // Hence, we have _potential_ sp-maybe functions left; the call
          // needs to be rewritten to point to the sp-maybe clone.
          rewriteCall(MI);
          // set _sp MF to single path in PMFI (MF has changed!)
          MachineFunction *MF = getCallTargetMF(MI);
          PatmosMachineFunctionInfo *PMFI =
            MF->getInfo<PatmosMachineFunctionInfo>();
          // we possibly have already marked the _sp variant as single-path
          // in an earlier call, if not, then set this final decision.
          if (!PMFI->isSinglePath()) {
            PMFI->setSinglePath();
            // add the new single-path function to the worklist
            W.push_back(MF);

            NumSPTotal++; // bump STATISTIC
            NumSPMaybe++; // bump STATISTIC
          }
        }
      }
    }
  }
}
コード例 #5
0
    //
    // Computes path_summary_iterative_original
    //
    void
    WFA::path_summary_iterative_original(Worklist<State>& wl, sem_elem_t wt)
    {
      // BEGIN DEBUGGING
      //int numPops = 0;
      // END DEBUGGING
      IncomingTransMap_t preds;
      setupFixpoint(wl, &preds, NULL, wt);
      while (!wl.empty()) {
        State* q = wl.get();
        sem_elem_t the_delta = q->delta();
        q->delta() = the_delta->zero();

        { // BEGIN DEBUGGING
          //numPops++;
          //q->print(*waliErr << "  Popped: ") << std::endl;
        } // END DEBUGGING

        // Get a handle on ZERO b/c we use it alot
        sem_elem_t ZERO = q->weight()->zero();

        // Find predecessor set
        IncomingTransMap_t::iterator incomingTransIt = preds.find(q->name());

        // Some states may have no predecessors, like
        // the initial state
        if (incomingTransIt == preds.end()) {
          continue;
        }

        // Tell predecessors we have changed
        std::vector<ITrans*> & incoming = incomingTransIt->second;

        std::vector<ITrans*>::iterator transit = incoming.begin();
        for ( ; transit != incoming.end() ; ++transit)
        {
          ITrans* t = *transit;
          
          // We are looking at a transition (q', _, q)
          State* qprime = state_map[t->from()];

          sem_elem_t newW = qprime->weight()->zero();

          { // BEGIN DEBUGGING
            //t->print(*waliErr << "\t++ Popped ") << std::endl;
          } // END DEBUGGING

          assert(t->to() == q->name());

          sem_elem_t extended;
          if (query == INORDER) {
            extended = t->weight()->extend(the_delta);
          }
          else {
            extended = the_delta->extend(t->weight());
          }
          newW = newW->combine(extended);

          // delta => (w+se,w-se)
          // Use extended->delta b/c we want the diff b/w the new
          // weight (extended) and what was there before
          std::pair<sem_elem_t,sem_elem_t> p = newW->delta(qprime->weight());

          { // BEGIN DEBUGGING
            //qprime->weight()->print(*waliErr << "   oldW " << key2str(qprime->name())) << std::endl;
            //newW->print(*waliErr << "   newW " << key2str(qprime->name())) << std::endl;
            //p.first->print(*waliErr << "\t++ p.first ") << std::endl;
            //p.second->print(*waliErr << "\t++ p.second ") << std::endl;
          } // END DEBUGGING

          // Sets qprime's new weight
          // p.first == (l(t) X the_delta) + W(qprime)
          qprime->weight() = p.first;

          // on the worklist?
          if (qprime->marked()) {
            qprime->delta() = qprime->delta()->combine(p.second);
          }
          else {
            // not on the worklist means its delta is zero
            qprime->delta() = p.second;

            // add to worklist if not zero
            if (!qprime->delta()->equal(ZERO)) {
              wl.put(qprime);
            }
          }
        }
        if (progress.is_valid()) {
            progress->tick();
        }
      }
      { // BEGIN DEBUGGING
        //*waliErr << "\n --- WFA::path_summary_iterative_original needed " << numPops << " pops\n";
        //*waliErr << "WFA state labels:\n";
        //FOR_EACH_STATE(st) {
        //    *waliErr << "\t" << key2str(st->name()) << ": ";
        //    st->weight()->print(*waliErr) << std::endl;
        //}
      } // END DEBUGGING
    }
コード例 #6
0
bool PatmosSPMark::runOnMachineModule(const Module &M) {

  DEBUG( dbgs() <<
         "[Single-Path] Mark functions reachable from single-path roots\n");

  MMI = &getAnalysis<MachineModuleInfo>();
  assert(MMI);

  Worklist W;

  // initialize the worklist with machine functions that have either
  // sp-root or sp-reachable function attribute
  for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) {
    if (F->hasFnAttribute("sp-root") || F->hasFnAttribute("sp-reachable")) {
      // get the machine-level function
      MachineFunction *MF = MMI->getMachineFunction(F);
      assert( MF );
      PatmosMachineFunctionInfo *PMFI =
        MF->getInfo<PatmosMachineFunctionInfo>();
      PMFI->setSinglePath();
      NumSPTotal++; // bump STATISTIC
      W.push_back(MF);
    }
  }

  // process worklist
  while (!W.empty()) {
    MachineFunction *MF = W.front();
    W.pop_front();
    scanAndRewriteCalls(MF, W);
  }

  // clear all cloned machine functions that are not marked as single-path
  // by now
  for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) {
    if (F->hasFnAttribute("sp-maybe")) {
      // get the machine-level function
      MachineFunction *MF = MMI->getMachineFunction(F);
      assert( MF );
      PatmosMachineFunctionInfo *PMFI =
        MF->getInfo<PatmosMachineFunctionInfo>();

      if (!PMFI->isSinglePath()) {
        // delete all MBBs
        while (MF->begin() != MF->end()) {
          MF->begin()->eraseFromParent();
        }
        // insert a new single MBB with a single return instruction
        MachineBasicBlock *EmptyMBB = MF->CreateMachineBasicBlock();
        MF->push_back(EmptyMBB);

        DebugLoc DL;
        AddDefaultPred(BuildMI(*EmptyMBB, EmptyMBB->end(), DL,
            TM.getInstrInfo()->get(Patmos::RET)));

        NumSPCleared++; // bump STATISTIC
      };
    }
  }

  return true;
}