Esempio n. 1
0
bool StackProtector::runOnFunction(Function &Fn) {
  F = &Fn;
  M = F->getParent();
  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DT = DTWP ? &DTWP->getDomTree() : nullptr;
  TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
  HasPrologue = false;
  HasIRCheck = false;

  Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
  if (Attr.isStringAttribute() &&
      Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
    return false; // Invalid integer string

  if (!RequiresStackProtector())
    return false;

  // TODO(etienneb): Functions with funclets are not correctly supported now.
  // Do nothing if this is funclet-based personality.
  if (Fn.hasPersonalityFn()) {
    EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());
    if (isFuncletEHPersonality(Personality))
      return false;
  }

  ++NumFunProtected;
  return InsertStackProtectors();
}
Esempio n. 2
0
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
  if (skipOptnoneFunction(L))
    return false;

  LI = &getAnalysis<LoopInfo>();
  LPM = &LPM_Ref;
  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DT = DTWP ? &DTWP->getDomTree() : 0;
  currentLoop = L;
  Function *F = currentLoop->getHeader()->getParent();
  bool Changed = false;
  do {
    assert(currentLoop->isLCSSAForm(*DT));
    redoLoop = false;
    Changed |= processCurrentLoop();
  } while(redoLoop);

  if (Changed) {
    // FIXME: Reconstruct dom info, because it is not preserved properly.
    if (DT)
      DT->recalculate(*F);
  }
  return Changed;
}
Esempio n. 3
0
void LowerEmAsyncify::FindContextVariables(AsyncCallEntry & Entry) {
  BasicBlock *AfterCallBlock = Entry.AfterCallBlock;

  Function & F = *AfterCallBlock->getParent();

  // Create a new entry block as if in the callback function
  // theck check variables that no longer properly dominate their uses
  BasicBlock *EntryBlock = BasicBlock::Create(TheModule->getContext(), "", &F, &F.getEntryBlock());
  BranchInst::Create(AfterCallBlock, EntryBlock);

  DominatorTreeWrapperPass DTW;
  DTW.runOnFunction(F);
  DominatorTree& DT = DTW.getDomTree();

  // These blocks may be using some values defined at or before AsyncCallBlock
  BasicBlockSet Ramifications = FindReachableBlocksFrom(AfterCallBlock); 

  SmallPtrSet<Value*, 256> ContextVariables;
  Values Pending;

  // Examine the instructions, find all variables that we need to store in the context
  for (BasicBlockSet::iterator RI = Ramifications.begin(), RE = Ramifications.end(); RI != RE; ++RI) {
    for (BasicBlock::iterator I = (*RI)->begin(), E = (*RI)->end(); I != E; ++I) {
      for (unsigned i = 0, NumOperands = I->getNumOperands(); i < NumOperands; ++i) {
        Value *O = I->getOperand(i);
        if (Instruction *Inst = dyn_cast<Instruction>(O)) {
          if (Inst == Entry.AsyncCallInst) continue; // for the original async call, we will load directly from async return value
          if (ContextVariables.count(Inst) != 0)  continue; // already examined 

          if (!DT.dominates(Inst, I->getOperandUse(i))) {
            // `I` is using `Inst`, yet `Inst` does not dominate `I` if we arrive directly at AfterCallBlock
            // so we need to save `Inst` in the context
            ContextVariables.insert(Inst);
            Pending.push_back(Inst);
          }
        } else if (Argument *Arg = dyn_cast<Argument>(O)) {
          // count() should be as fast/slow as insert, so just insert here 
          ContextVariables.insert(Arg);
        }
      }
    }
  }

  // restore F
  EntryBlock->eraseFromParent();  

  Entry.ContextVariables.clear();
  Entry.ContextVariables.reserve(ContextVariables.size());
  for (SmallPtrSet<Value*, 256>::iterator I = ContextVariables.begin(), E = ContextVariables.end(); I != E; ++I) {
    Entry.ContextVariables.push_back(*I);
  }
}
Esempio n. 4
0
bool LazyValueInfo::runOnFunction(Function &F) {
  AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
  const DataLayout &DL = F.getParent()->getDataLayout();

  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DT = DTWP ? &DTWP->getDomTree() : nullptr;

  TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();

  if (PImpl)
    getCache(PImpl, AC, &DL, DT).clear();

  // Fully lazy.
  return false;
}
Esempio n. 5
0
bool StackProtector::runOnFunction(Function &Fn) {
  F = &Fn;
  M = F->getParent();
  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DT = DTWP ? &DTWP->getDomTree() : nullptr;
  TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();

  Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
  if (Attr.isStringAttribute() &&
      Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
      return false; // Invalid integer string

  if (!RequiresStackProtector())
    return false;

  ++NumFunProtected;
  return InsertStackProtectors();
}
Esempio n. 6
0
bool StackProtector::runOnFunction(Function &Fn) {
  F = &Fn;
  M = F->getParent();
  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DT = DTWP ? &DTWP->getDomTree() : 0;
  TLI = TM->getTargetLowering();

  if (!RequiresStackProtector())
    return false;

  Attribute Attr = Fn.getAttributes().getAttribute(
      AttributeSet::FunctionIndex, "stack-protector-buffer-size");
  if (Attr.isStringAttribute())
    Attr.getValueAsString().getAsInteger(10, SSPBufferSize);

  ++NumFunProtected;
  return InsertStackProtectors();
}
void doMemToReg(Function &F) {
  std::vector<AllocaInst*> Allocas;

  BasicBlock &BB = F.getEntryBlock();  // Get the entry node for the function

  DominatorTreeWrapperPass DTW;
  DTW.runOnFunction(F);
  DominatorTree& DT = DTW.getDomTree();

  while (1) {
    Allocas.clear();

    // Find allocas that are safe to promote, by looking at all instructions in
    // the entry node
    for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))       // Is it an alloca?
        if (isAllocaPromotable(AI))
          Allocas.push_back(AI);

    if (Allocas.empty()) break;

    PromoteMemToReg(Allocas, DT);
  }
}
bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
  if (skipOptnoneFunction(L))
    return false;

  DominatorTreeWrapperPass *DTWP =
      getAnalysisIfAvailable<DominatorTreeWrapperPass>();
  DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
  LoopInfo *LI = &getAnalysis<LoopInfo>();
  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
  const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr;
  const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
  AssumptionTracker *AT = &getAnalysis<AssumptionTracker>();

  SmallVector<BasicBlock*, 8> ExitBlocks;
  L->getUniqueExitBlocks(ExitBlocks);
  array_pod_sort(ExitBlocks.begin(), ExitBlocks.end());

  SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;

  // The bit we are stealing from the pointer represents whether this basic
  // block is the header of a subloop, in which case we only process its phis.
  typedef PointerIntPair<BasicBlock*, 1> WorklistItem;
  SmallVector<WorklistItem, 16> VisitStack;
  SmallPtrSet<BasicBlock*, 32> Visited;

  bool Changed = false;
  bool LocalChanged;
  do {
    LocalChanged = false;

    VisitStack.clear();
    Visited.clear();

    VisitStack.push_back(WorklistItem(L->getHeader(), false));

    while (!VisitStack.empty()) {
      WorklistItem Item = VisitStack.pop_back_val();
      BasicBlock *BB = Item.getPointer();
      bool IsSubloopHeader = Item.getInt();

      // Simplify instructions in the current basic block.
      for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
        Instruction *I = BI++;

        // The first time through the loop ToSimplify is empty and we try to
        // simplify all instructions. On later iterations ToSimplify is not
        // empty and we only bother simplifying instructions that are in it.
        if (!ToSimplify->empty() && !ToSimplify->count(I))
          continue;

        // Don't bother simplifying unused instructions.
        if (!I->use_empty()) {
          Value *V = SimplifyInstruction(I, DL, TLI, DT, AT);
          if (V && LI->replacementPreservesLCSSAForm(I, V)) {
            // Mark all uses for resimplification next time round the loop.
            for (User *U : I->users())
              Next->insert(cast<Instruction>(U));

            I->replaceAllUsesWith(V);
            LocalChanged = true;
            ++NumSimplified;
          }
        }
        bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
        if (res) {
          // RecursivelyDeleteTriviallyDeadInstruction can remove
          // more than one instruction, so simply incrementing the
          // iterator does not work. When instructions get deleted
          // re-iterate instead.
          BI = BB->begin(); BE = BB->end();
          LocalChanged |= res;
        }

        if (IsSubloopHeader && !isa<PHINode>(I))
          break;
      }

      // Add all successors to the worklist, except for loop exit blocks and the
      // bodies of subloops. We visit the headers of loops so that we can process
      // their phis, but we contract the rest of the subloop body and only follow
      // edges leading back to the original loop.
      for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE;
           ++SI) {
        BasicBlock *SuccBB = *SI;
        if (!Visited.insert(SuccBB).second)
          continue;

        const Loop *SuccLoop = LI->getLoopFor(SuccBB);
        if (SuccLoop && SuccLoop->getHeader() == SuccBB
                     && L->contains(SuccLoop)) {
          VisitStack.push_back(WorklistItem(SuccBB, true));

          SmallVector<BasicBlock*, 8> SubLoopExitBlocks;
          SuccLoop->getExitBlocks(SubLoopExitBlocks);

          for (unsigned i = 0; i < SubLoopExitBlocks.size(); ++i) {
            BasicBlock *ExitBB = SubLoopExitBlocks[i];
            if (LI->getLoopFor(ExitBB) == L && Visited.insert(ExitBB).second)
              VisitStack.push_back(WorklistItem(ExitBB, false));
          }

          continue;
        }

        bool IsExitBlock = std::binary_search(ExitBlocks.begin(),
                                              ExitBlocks.end(), SuccBB);
        if (IsExitBlock)
          continue;

        VisitStack.push_back(WorklistItem(SuccBB, false));
      }
    }

    // Place the list of instructions to simplify on the next loop iteration
    // into ToSimplify.
    std::swap(ToSimplify, Next);
    Next->clear();

    Changed |= LocalChanged;
  } while (LocalChanged);

  return Changed;
}
Esempio n. 9
0
void LowerEmAsyncify::transformAsyncFunction(Function &F, Instructions const& AsyncCalls) {
  assert(!AsyncCalls.empty());

  // Pass 0
  // collect all the return instructions from the original function
  // will use later
  std::vector<ReturnInst*> OrigReturns;
  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
    if (ReturnInst *RI = dyn_cast<ReturnInst>(&*I)) {
      OrigReturns.push_back(RI);
    }
  }

  // Pass 1
  // Scan each async call and make the basic structure:
  // All these will be cloned into the callback functions
  // - allocate the async context before calling an async function
  // - check async right after calling an async function, save context & return if async, continue if not
  // - retrieve the async return value and free the async context if the called function turns out to be sync
  std::vector<AsyncCallEntry> AsyncCallEntries;
  AsyncCallEntries.reserve(AsyncCalls.size());
  for (Instructions::const_iterator I = AsyncCalls.begin(), E = AsyncCalls.end(); I != E; ++I) {
    // prepare blocks
    Instruction *CurAsyncCall = *I;

    // The block containing the async call
    BasicBlock *CurBlock = CurAsyncCall->getParent();
    // The block should run after the async call
    BasicBlock *AfterCallBlock = SplitBlock(CurBlock, CurAsyncCall->getNextNode());
    // The block where we store the context and return
    BasicBlock *SaveAsyncCtxBlock = BasicBlock::Create(TheModule->getContext(), "SaveAsyncCtx", &F, AfterCallBlock);
    // return a dummy value at the end, to make the block valid
    new UnreachableInst(TheModule->getContext(), SaveAsyncCtxBlock);

    // allocate the context before making the call
    // we don't know the size yet, will fix it later
    // we cannot insert the instruction later because,
    // we need to make sure that all the instructions and blocks are fixed before we can generate DT and find context variables
    // In CallHandler.h `sp` will be put as the second parameter
    // such that we can take a note of the original sp 
    CallInst *AllocAsyncCtxInst = CallInst::Create(AllocAsyncCtxFunction, Constant::getNullValue(I32), "AsyncCtx", CurAsyncCall);

    // Right after the call
    // check async and return if so
    // TODO: we can define truly async functions and partial async functions
    {
      // remove old terminator, which came from SplitBlock
      CurBlock->getTerminator()->eraseFromParent();
      // go to SaveAsyncCtxBlock if the previous call is async
      // otherwise just continue to AfterCallBlock
      CallInst *CheckAsync = CallInst::Create(CheckAsyncFunction, "IsAsync", CurBlock);
      BranchInst::Create(SaveAsyncCtxBlock, AfterCallBlock, CheckAsync, CurBlock);
    }

    // take a note of this async call
    AsyncCallEntry CurAsyncCallEntry;
    CurAsyncCallEntry.AsyncCallInst = CurAsyncCall;
    CurAsyncCallEntry.AfterCallBlock = AfterCallBlock;
    CurAsyncCallEntry.AllocAsyncCtxInst = AllocAsyncCtxInst;
    CurAsyncCallEntry.SaveAsyncCtxBlock = SaveAsyncCtxBlock;
    // create an empty function for the callback, which will be constructed later
    CurAsyncCallEntry.CallbackFunc = Function::Create(CallbackFunctionType, F.getLinkage(), F.getName() + "__async_cb", TheModule);
    AsyncCallEntries.push_back(CurAsyncCallEntry);
  }


  // Pass 2
  // analyze the context variables and construct SaveAsyncCtxBlock for each async call
  // also calculate the size of the context and allocate the async context accordingly
  for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end();  EI != EE; ++EI) {
    AsyncCallEntry & CurEntry = *EI;

    // Collect everything to be saved
    FindContextVariables(CurEntry);

    // Pack the variables as a struct
    {
      // TODO: sort them from large memeber to small ones, in order to make the struct compact even when aligned
      SmallVector<Type*, 8> Types;
      Types.push_back(CallbackFunctionType->getPointerTo());
      for (Values::iterator VI = CurEntry.ContextVariables.begin(), VE = CurEntry.ContextVariables.end(); VI != VE; ++VI) {
        Types.push_back((*VI)->getType());
      }
      CurEntry.ContextStructType = StructType::get(TheModule->getContext(), Types);
    }

    // fix the size of allocation
    CurEntry.AllocAsyncCtxInst->setOperand(0, 
        ConstantInt::get(I32, DL->getTypeStoreSize(CurEntry.ContextStructType)));

    // construct SaveAsyncCtxBlock
    {
      // fill in SaveAsyncCtxBlock
      // temporarily remove the terminator for convenience
      CurEntry.SaveAsyncCtxBlock->getTerminator()->eraseFromParent();
      assert(CurEntry.SaveAsyncCtxBlock->empty());

      Type *AsyncCtxAddrTy = CurEntry.ContextStructType->getPointerTo();
      BitCastInst *AsyncCtxAddr = new BitCastInst(CurEntry.AllocAsyncCtxInst, AsyncCtxAddrTy, "AsyncCtxAddr", CurEntry.SaveAsyncCtxBlock);
      SmallVector<Value*, 2> Indices;
      // store the callback
      {
        Indices.push_back(ConstantInt::get(I32, 0));
        Indices.push_back(ConstantInt::get(I32, 0));
        GetElementPtrInst *AsyncVarAddr = GetElementPtrInst::Create(AsyncCtxAddrTy, AsyncCtxAddr, Indices, "", CurEntry.SaveAsyncCtxBlock);
        new StoreInst(CurEntry.CallbackFunc, AsyncVarAddr, CurEntry.SaveAsyncCtxBlock);
      }
      // store the context variables
      for (size_t i = 0; i < CurEntry.ContextVariables.size(); ++i) {
        Indices.clear();
        Indices.push_back(ConstantInt::get(I32, 0));
        Indices.push_back(ConstantInt::get(I32, i + 1)); // the 0th element is the callback function
        GetElementPtrInst *AsyncVarAddr = GetElementPtrInst::Create(AsyncCtxAddrTy, AsyncCtxAddr, Indices, "", CurEntry.SaveAsyncCtxBlock);
        new StoreInst(CurEntry.ContextVariables[i], AsyncVarAddr, CurEntry.SaveAsyncCtxBlock);
      }
      // to exit the block, we want to return without unwinding the stack frame
      CallInst::Create(DoNotUnwindFunction, "", CurEntry.SaveAsyncCtxBlock);
      ReturnInst::Create(TheModule->getContext(), 
          (F.getReturnType()->isVoidTy() ? 0 : Constant::getNullValue(F.getReturnType())),
          CurEntry.SaveAsyncCtxBlock);
    }
  }

  // Pass 3
  // now all the SaveAsyncCtxBlock's have been constructed
  // we can clone F and construct callback functions 
  // we could not construct the callbacks in Pass 2 because we need _all_ those SaveAsyncCtxBlock's appear in _each_ callback
  for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end();  EI != EE; ++EI) {
    AsyncCallEntry & CurEntry = *EI;

    Function *CurCallbackFunc = CurEntry.CallbackFunc;
    ValueToValueMapTy VMap;

    // Add the entry block
    // load variables from the context
    // also update VMap for CloneFunction
    BasicBlock *EntryBlock = BasicBlock::Create(TheModule->getContext(), "AsyncCallbackEntry", CurCallbackFunc);
    std::vector<LoadInst *> LoadedAsyncVars;
    {
      Type *AsyncCtxAddrTy = CurEntry.ContextStructType->getPointerTo();
      BitCastInst *AsyncCtxAddr = new BitCastInst(CurCallbackFunc->arg_begin(), AsyncCtxAddrTy, "AsyncCtx", EntryBlock);
      SmallVector<Value*, 2> Indices;
      for (size_t i = 0; i < CurEntry.ContextVariables.size(); ++i) {
        Indices.clear();
        Indices.push_back(ConstantInt::get(I32, 0));
        Indices.push_back(ConstantInt::get(I32, i + 1)); // the 0th element of AsyncCtx is the callback function
        GetElementPtrInst *AsyncVarAddr = GetElementPtrInst::Create(AsyncCtxAddrTy, AsyncCtxAddr, Indices, "", EntryBlock);
        LoadedAsyncVars.push_back(new LoadInst(AsyncVarAddr, "", EntryBlock));
        // we want the argument to be replaced by the loaded value
        if (isa<Argument>(CurEntry.ContextVariables[i]))
          VMap[CurEntry.ContextVariables[i]] = LoadedAsyncVars.back();
      }
    }

    // we don't need any argument, just leave dummy entries there to cheat CloneFunctionInto
    for (Function::const_arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) {
      if (VMap.count(AI) == 0)
        VMap[AI] = Constant::getNullValue(AI->getType());
    }

    // Clone the function
    {
      SmallVector<ReturnInst*, 8> Returns;
      CloneFunctionInto(CurCallbackFunc, &F, VMap, false, Returns);
      
      // return type of the callback functions is always void
      // need to fix the return type
      if (!F.getReturnType()->isVoidTy()) {
        // for those return instructions that are from the original function
        // it means we are 'truly' leaving this function
        // need to store the return value right before ruturn
        for (size_t i = 0; i < OrigReturns.size(); ++i) {
          ReturnInst *RI = cast<ReturnInst>(VMap[OrigReturns[i]]);
          // Need to store the return value into the global area
          CallInst *RawRetValAddr = CallInst::Create(GetAsyncReturnValueAddrFunction, "", RI);
          BitCastInst *RetValAddr = new BitCastInst(RawRetValAddr, F.getReturnType()->getPointerTo(), "AsyncRetValAddr", RI);
          new StoreInst(RI->getOperand(0), RetValAddr, RI);
        }
        // we want to unwind the stack back to where it was before the original function as called
        // but we don't actually need to do this here
        // at this point it must be true that no callback is pended
        // so the scheduler will correct the stack pointer and pop the frame
        // here we just fix the return type
        for (size_t i = 0; i < Returns.size(); ++i) {
          ReplaceInstWithInst(Returns[i], ReturnInst::Create(TheModule->getContext()));
        }
      }
    }

    // the callback function does not have any return value
    // so clear all the attributes for return
    {
      AttributeSet Attrs = CurCallbackFunc->getAttributes();
      CurCallbackFunc->setAttributes(
        Attrs.removeAttributes(TheModule->getContext(), AttributeSet::ReturnIndex, Attrs.getRetAttributes())
      );
    }

    // in the callback function, we never allocate a new async frame
    // instead we reuse the existing one
    for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end();  EI != EE; ++EI) {
      Instruction *I = cast<Instruction>(VMap[EI->AllocAsyncCtxInst]);
      ReplaceInstWithInst(I, CallInst::Create(ReallocAsyncCtxFunction, I->getOperand(0), "ReallocAsyncCtx"));
    }

    // mapped entry point & async call
    BasicBlock *ResumeBlock = cast<BasicBlock>(VMap[CurEntry.AfterCallBlock]);
    Instruction *MappedAsyncCall = cast<Instruction>(VMap[CurEntry.AsyncCallInst]);
   
    // To save space, for each async call in the callback function, we just ignore the sync case, and leave it to the scheduler
    // TODO need an option for this
    {
      for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end();  EI != EE; ++EI) {
        AsyncCallEntry & CurEntry = *EI;
        Instruction *MappedAsyncCallInst = cast<Instruction>(VMap[CurEntry.AsyncCallInst]);
        BasicBlock *MappedAsyncCallBlock = MappedAsyncCallInst->getParent();
        BasicBlock *MappedAfterCallBlock = cast<BasicBlock>(VMap[CurEntry.AfterCallBlock]);

        // for the sync case of the call, go to NewBlock (instead of MappedAfterCallBlock)
        BasicBlock *NewBlock = BasicBlock::Create(TheModule->getContext(), "", CurCallbackFunc, MappedAfterCallBlock);
        MappedAsyncCallBlock->getTerminator()->setSuccessor(1, NewBlock);
        // store the return value
        if (!MappedAsyncCallInst->use_empty()) {
          CallInst *RawRetValAddr = CallInst::Create(GetAsyncReturnValueAddrFunction, "", NewBlock);
          BitCastInst *RetValAddr = new BitCastInst(RawRetValAddr, MappedAsyncCallInst->getType()->getPointerTo(), "AsyncRetValAddr", NewBlock);
          new StoreInst(MappedAsyncCallInst, RetValAddr, NewBlock);
        }
        // tell the scheduler that we want to keep the current async stack frame
        CallInst::Create(DoNotUnwindAsyncFunction, "", NewBlock);
        // finally we go to the SaveAsyncCtxBlock, to register the callbac, save the local variables and leave
        BasicBlock *MappedSaveAsyncCtxBlock = cast<BasicBlock>(VMap[CurEntry.SaveAsyncCtxBlock]);
        BranchInst::Create(MappedSaveAsyncCtxBlock, NewBlock);
      }
    }

    std::vector<AllocaInst*> ToPromote;
    // applying loaded variables in the entry block
    {
      BasicBlockSet ReachableBlocks = FindReachableBlocksFrom(ResumeBlock);
      for (size_t i = 0; i < CurEntry.ContextVariables.size(); ++i) {
        Value *OrigVar = CurEntry.ContextVariables[i];
        if (isa<Argument>(OrigVar)) continue; // already processed
        Value *CurVar = VMap[OrigVar];
        assert(CurVar != MappedAsyncCall);
        if (Instruction *Inst = dyn_cast<Instruction>(CurVar)) {
          if (ReachableBlocks.count(Inst->getParent())) {
            // Inst could be either defined or loaded from the async context
            // Do the dirty works in memory
            // TODO: might need to check the safety first
            // TODO: can we create phi directly?
            AllocaInst *Addr = DemoteRegToStack(*Inst, false);
            new StoreInst(LoadedAsyncVars[i], Addr, EntryBlock);
            ToPromote.push_back(Addr);
          } else {
            // The parent block is not reachable, which means there is no confliction
            // it's safe to replace Inst with the loaded value
            assert(Inst != LoadedAsyncVars[i]); // this should only happen when OrigVar is an Argument
            Inst->replaceAllUsesWith(LoadedAsyncVars[i]); 
          }
        }
      }
    }

    // resolve the return value of the previous async function
    // it could be the value just loaded from the global area
    // or directly returned by the function (in its sync case)
    if (!CurEntry.AsyncCallInst->use_empty()) {
      // load the async return value
      CallInst *RawRetValAddr = CallInst::Create(GetAsyncReturnValueAddrFunction, "", EntryBlock);
      BitCastInst *RetValAddr = new BitCastInst(RawRetValAddr, MappedAsyncCall->getType()->getPointerTo(), "AsyncRetValAddr", EntryBlock);
      LoadInst *RetVal = new LoadInst(RetValAddr, "AsyncRetVal", EntryBlock);

      AllocaInst *Addr = DemoteRegToStack(*MappedAsyncCall, false);
      new StoreInst(RetVal, Addr, EntryBlock);
      ToPromote.push_back(Addr);
    }

    // TODO remove unreachable blocks before creating phi
   
    // We go right to ResumeBlock from the EntryBlock
    BranchInst::Create(ResumeBlock, EntryBlock);
   
    /*
     * Creating phi's
     * Normal stack frames and async stack frames are interleaving with each other.
     * In a callback function, if we call an async function, we might need to realloc the async ctx.
     * at this point we don't want anything stored after the ctx, 
     * such that we can free and extend the ctx by simply update STACKTOP.
     * Therefore we don't want any alloca's in callback functions.
     *
     */
    if (!ToPromote.empty()) {
      DominatorTreeWrapperPass DTW;
      DTW.runOnFunction(*CurCallbackFunc);
      PromoteMemToReg(ToPromote, DTW.getDomTree());
    }

    removeUnreachableBlocks(*CurCallbackFunc);
  }

  // Pass 4
  // Here are modifications to the original function, which we won't want to be cloned into the callback functions
  for (std::vector<AsyncCallEntry>::iterator EI = AsyncCallEntries.begin(), EE = AsyncCallEntries.end();  EI != EE; ++EI) {
    AsyncCallEntry & CurEntry = *EI;
    // remove the frame if no async functinon has been called
    CallInst::Create(FreeAsyncCtxFunction, CurEntry.AllocAsyncCtxInst, "", CurEntry.AfterCallBlock->getFirstNonPHI());
  }
}
Esempio n. 10
0
/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
/// split the critical edge.  This will update DominatorTree information if it
/// is available, thus calling this pass will not invalidate either of them.
/// This returns the new block if the edge was split, null otherwise.
///
/// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the
/// specified successor will be merged into the same critical edge block.
/// This is most commonly interesting with switch instructions, which may
/// have many edges to any one destination.  This ensures that all edges to that
/// dest go to one block instead of each going to a different block, but isn't
/// the standard definition of a "critical edge".
///
/// It is invalid to call this function on a critical edge that starts at an
/// IndirectBrInst.  Splitting these edges will almost always create an invalid
/// program because the address of the new block won't be the one that is jumped
/// to.
///
BasicBlock *llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
                                    Pass *P, bool MergeIdenticalEdges,
                                    bool DontDeleteUselessPhis,
                                    bool SplitLandingPads) {
    if (!isCriticalEdge(TI, SuccNum, MergeIdenticalEdges)) return 0;

    assert(!isa<IndirectBrInst>(TI) &&
           "Cannot split critical edge from IndirectBrInst");

    BasicBlock *TIBB = TI->getParent();
    BasicBlock *DestBB = TI->getSuccessor(SuccNum);

    // Splitting the critical edge to a landing pad block is non-trivial. Don't do
    // it in this generic function.
    if (DestBB->isLandingPad()) return 0;

    // Create a new basic block, linking it into the CFG.
    BasicBlock *NewBB = BasicBlock::Create(TI->getContext(),
                                           TIBB->getName() + "." + DestBB->getName() + "_crit_edge");
    // Create our unconditional branch.
    BranchInst *NewBI = BranchInst::Create(DestBB, NewBB);
    NewBI->setDebugLoc(TI->getDebugLoc());

    // Branch to the new block, breaking the edge.
    TI->setSuccessor(SuccNum, NewBB);

    // Insert the block into the function... right after the block TI lives in.
    Function &F = *TIBB->getParent();
    Function::iterator FBBI = TIBB;
    F.getBasicBlockList().insert(++FBBI, NewBB);

    // If there are any PHI nodes in DestBB, we need to update them so that they
    // merge incoming values from NewBB instead of from TIBB.
    {
        unsigned BBIdx = 0;
        for (BasicBlock::iterator I = DestBB->begin(); isa<PHINode>(I); ++I) {
            // We no longer enter through TIBB, now we come in through NewBB.
            // Revector exactly one entry in the PHI node that used to come from
            // TIBB to come from NewBB.
            PHINode *PN = cast<PHINode>(I);

            // Reuse the previous value of BBIdx if it lines up.  In cases where we
            // have multiple phi nodes with *lots* of predecessors, this is a speed
            // win because we don't have to scan the PHI looking for TIBB.  This
            // happens because the BB list of PHI nodes are usually in the same
            // order.
            if (PN->getIncomingBlock(BBIdx) != TIBB)
                BBIdx = PN->getBasicBlockIndex(TIBB);
            PN->setIncomingBlock(BBIdx, NewBB);
        }
    }

    // If there are any other edges from TIBB to DestBB, update those to go
    // through the split block, making those edges non-critical as well (and
    // reducing the number of phi entries in the DestBB if relevant).
    if (MergeIdenticalEdges) {
        for (unsigned i = SuccNum+1, e = TI->getNumSuccessors(); i != e; ++i) {
            if (TI->getSuccessor(i) != DestBB) continue;

            // Remove an entry for TIBB from DestBB phi nodes.
            DestBB->removePredecessor(TIBB, DontDeleteUselessPhis);

            // We found another edge to DestBB, go to NewBB instead.
            TI->setSuccessor(i, NewBB);
        }
    }



    // If we don't have a pass object, we can't update anything...
    if (P == 0) return NewBB;

    DominatorTreeWrapperPass *DTWP =
        P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
    DominatorTree *DT = DTWP ? &DTWP->getDomTree() : 0;
    LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();

    // If we have nothing to update, just return.
    if (DT == 0 && LI == 0)
        return NewBB;

    // Now update analysis information.  Since the only predecessor of NewBB is
    // the TIBB, TIBB clearly dominates NewBB.  TIBB usually doesn't dominate
    // anything, as there are other successors of DestBB.  However, if all other
    // predecessors of DestBB are already dominated by DestBB (e.g. DestBB is a
    // loop header) then NewBB dominates DestBB.
    SmallVector<BasicBlock*, 8> OtherPreds;

    // If there is a PHI in the block, loop over predecessors with it, which is
    // faster than iterating pred_begin/end.
    if (PHINode *PN = dyn_cast<PHINode>(DestBB->begin())) {
        for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
            if (PN->getIncomingBlock(i) != NewBB)
                OtherPreds.push_back(PN->getIncomingBlock(i));
    } else {
        for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB);
                I != E; ++I) {
            BasicBlock *P = *I;
            if (P != NewBB)
                OtherPreds.push_back(P);
        }
    }

    bool NewBBDominatesDestBB = true;

    // Should we update DominatorTree information?
    if (DT) {
        DomTreeNode *TINode = DT->getNode(TIBB);

        // The new block is not the immediate dominator for any other nodes, but
        // TINode is the immediate dominator for the new node.
        //
        if (TINode) {       // Don't break unreachable code!
            DomTreeNode *NewBBNode = DT->addNewBlock(NewBB, TIBB);
            DomTreeNode *DestBBNode = 0;

            // If NewBBDominatesDestBB hasn't been computed yet, do so with DT.
            if (!OtherPreds.empty()) {
                DestBBNode = DT->getNode(DestBB);
                while (!OtherPreds.empty() && NewBBDominatesDestBB) {
                    if (DomTreeNode *OPNode = DT->getNode(OtherPreds.back()))
                        NewBBDominatesDestBB = DT->dominates(DestBBNode, OPNode);
                    OtherPreds.pop_back();
                }
                OtherPreds.clear();
            }

            // If NewBBDominatesDestBB, then NewBB dominates DestBB, otherwise it
            // doesn't dominate anything.
            if (NewBBDominatesDestBB) {
                if (!DestBBNode) DestBBNode = DT->getNode(DestBB);
                DT->changeImmediateDominator(DestBBNode, NewBBNode);
            }
        }
    }

    // Update LoopInfo if it is around.
    if (LI) {
        if (Loop *TIL = LI->getLoopFor(TIBB)) {
            // If one or the other blocks were not in a loop, the new block is not
            // either, and thus LI doesn't need to be updated.
            if (Loop *DestLoop = LI->getLoopFor(DestBB)) {
                if (TIL == DestLoop) {
                    // Both in the same loop, the NewBB joins loop.
                    DestLoop->addBasicBlockToLoop(NewBB, LI->getBase());
                } else if (TIL->contains(DestLoop)) {
                    // Edge from an outer loop to an inner loop.  Add to the outer loop.
                    TIL->addBasicBlockToLoop(NewBB, LI->getBase());
                } else if (DestLoop->contains(TIL)) {
                    // Edge from an inner loop to an outer loop.  Add to the outer loop.
                    DestLoop->addBasicBlockToLoop(NewBB, LI->getBase());
                } else {
                    // Edge from two loops with no containment relation.  Because these
                    // are natural loops, we know that the destination block must be the
                    // header of its loop (adding a branch into a loop elsewhere would
                    // create an irreducible loop).
                    assert(DestLoop->getHeader() == DestBB &&
                           "Should not create irreducible loops!");
                    if (Loop *P = DestLoop->getParentLoop())
                        P->addBasicBlockToLoop(NewBB, LI->getBase());
                }
            }
            // If TIBB is in a loop and DestBB is outside of that loop, we may need
            // to update LoopSimplify form and LCSSA form.
            if (!TIL->contains(DestBB) &&
                    P->mustPreserveAnalysisID(LoopSimplifyID)) {
                assert(!TIL->contains(NewBB) &&
                       "Split point for loop exit is contained in loop!");

                // Update LCSSA form in the newly created exit block.
                if (P->mustPreserveAnalysisID(LCSSAID))
                    createPHIsForSplitLoopExit(TIBB, NewBB, DestBB);

                // The only that we can break LoopSimplify form by splitting a critical
                // edge is if after the split there exists some edge from TIL to DestBB
                // *and* the only edge into DestBB from outside of TIL is that of
                // NewBB. If the first isn't true, then LoopSimplify still holds, NewBB
                // is the new exit block and it has no non-loop predecessors. If the
                // second isn't true, then DestBB was not in LoopSimplify form prior to
                // the split as it had a non-loop predecessor. In both of these cases,
                // the predecessor must be directly in TIL, not in a subloop, or again
                // LoopSimplify doesn't hold.
                SmallVector<BasicBlock *, 4> LoopPreds;
                for (pred_iterator I = pred_begin(DestBB), E = pred_end(DestBB); I != E;
                        ++I) {
                    BasicBlock *P = *I;
                    if (P == NewBB)
                        continue; // The new block is known.
                    if (LI->getLoopFor(P) != TIL) {
                        // No need to re-simplify, it wasn't to start with.
                        LoopPreds.clear();
                        break;
                    }
                    LoopPreds.push_back(P);
                }
                if (!LoopPreds.empty()) {
                    assert(!DestBB->isLandingPad() &&
                           "We don't split edges to landing pads!");
                    BasicBlock *NewExitBB =
                        SplitBlockPredecessors(DestBB, LoopPreds, "split", P);
                    if (P->mustPreserveAnalysisID(LCSSAID))
                        createPHIsForSplitLoopExit(LoopPreds, NewExitBB, DestBB);
                }
            }
            // LCSSA form was updated above for the case where LoopSimplify is
            // available, which means that all predecessors of loop exit blocks
            // are within the loop. Without LoopSimplify form, it would be
            // necessary to insert a new phi.
            assert((!P->mustPreserveAnalysisID(LCSSAID) ||
                    P->mustPreserveAnalysisID(LoopSimplifyID)) &&
                   "SplitCriticalEdge doesn't know how to update LCCSA form "
                   "without LoopSimplify!");
        }
    }

    return NewBB;
}