Example #1
0
bool mssa::runOnFunction(Function &F) {
    
    MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
    //MemorySSAWalker MAW = new MemorySSAWalker(MSSA);
    errs()<<"\n";

    for (Function::iterator BB = F.begin(); BB != F.end(); BB++){
	errs() << "Basic block (name=" << BB->getName() << ")\n"; 
	
	//Get MemoryPhi and print it out
	MemoryPhi* MP = MSSA->getMemoryAccess(dyn_cast<BasicBlock>(BB));
	if (MP != NULL)
	    MP->dump();
        for (BasicBlock::iterator itrIns = (*BB).begin(); itrIns != (*BB).end(); itrIns++) {
	    //MemoryAccess* MA = MAW.getClobberingMemoryAccess(itrIns);
	    //MemoryLocation Location;
	    //MemoryAccess* MAR = MAW.getClobberingMemoryAccess(MA,&Location);
	    //MAR->dump();
	    errs()<<"Instruction: "<< *itrIns <<"\n";

	    //Get MemoryDef or MemoryUse and print it out
	    MemoryAccess *MA = MSSA->getMemoryAccess(dyn_cast<Value>(itrIns));
	    if (MA != NULL) {
	    	MA->dump();
		//if(MSSA->isLiveOnEntryDef(MA))

		//Get immediate MemoryDef of the instruction annotated MemoryDef/MemoryUse
    		for (memoryaccess_def_iterator MAitr = MA->defs_begin(); 
		     MAitr != MA->defs_end(); 
		     MAitr++)
		{
		     errs()<<"Def: "<<**MAitr<<"\n";
		     //Get the instruction the immediate Memory Def annotation represent
		     Instruction* u = cast<MemoryUseOrDef>(*MAitr)->getMemoryInst();
		     if (u != NULL)
			errs()<<"     Def Inst: "<<*u<<"\n";
		}	
	    }
	}
    }
    return 0;
}
static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI,
                             AssumptionCache &AC, const TargetLibraryInfo &TLI,
                             MemorySSAUpdater *MSSAU) {
  const DataLayout &DL = L.getHeader()->getModule()->getDataLayout();
  SimplifyQuery SQ(DL, &TLI, &DT, &AC);

  // On the first pass over the loop body we try to simplify every instruction.
  // On subsequent passes, we can restrict this to only simplifying instructions
  // where the inputs have been updated. We end up needing two sets: one
  // containing the instructions we are simplifying in *this* pass, and one for
  // the instructions we will want to simplify in the *next* pass. We use
  // pointers so we can swap between two stably allocated sets.
  SmallPtrSet<const Instruction *, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;

  // Track the PHI nodes that have already been visited during each iteration so
  // that we can identify when it is necessary to iterate.
  SmallPtrSet<PHINode *, 4> VisitedPHIs;

  // While simplifying we may discover dead code or cause code to become dead.
  // Keep track of all such instructions and we will delete them at the end.
  SmallVector<Instruction *, 8> DeadInsts;

  // First we want to create an RPO traversal of the loop body. By processing in
  // RPO we can ensure that definitions are processed prior to uses (for non PHI
  // uses) in all cases. This ensures we maximize the simplifications in each
  // iteration over the loop and minimizes the possible causes for continuing to
  // iterate.
  LoopBlocksRPO RPOT(&L);
  RPOT.perform(&LI);
  MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr;

  bool Changed = false;
  for (;;) {
    if (MSSAU && VerifyMemorySSA)
      MSSA->verifyMemorySSA();
    for (BasicBlock *BB : RPOT) {
      for (Instruction &I : *BB) {
        if (auto *PI = dyn_cast<PHINode>(&I))
          VisitedPHIs.insert(PI);

        if (I.use_empty()) {
          if (isInstructionTriviallyDead(&I, &TLI))
            DeadInsts.push_back(&I);
          continue;
        }

        // We special case the first iteration which we can detect due to the
        // empty `ToSimplify` set.
        bool IsFirstIteration = ToSimplify->empty();

        if (!IsFirstIteration && !ToSimplify->count(&I))
          continue;

        Value *V = SimplifyInstruction(&I, SQ.getWithInstruction(&I));
        if (!V || !LI.replacementPreservesLCSSAForm(&I, V))
          continue;

        for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
             UI != UE;) {
          Use &U = *UI++;
          auto *UserI = cast<Instruction>(U.getUser());
          U.set(V);

          // If the instruction is used by a PHI node we have already processed
          // we'll need to iterate on the loop body to converge, so add it to
          // the next set.
          if (auto *UserPI = dyn_cast<PHINode>(UserI))
            if (VisitedPHIs.count(UserPI)) {
              Next->insert(UserPI);
              continue;
            }

          // If we are only simplifying targeted instructions and the user is an
          // instruction in the loop body, add it to our set of targeted
          // instructions. Because we process defs before uses (outside of PHIs)
          // we won't have visited it yet.
          //
          // We also skip any uses outside of the loop being simplified. Those
          // should always be PHI nodes due to LCSSA form, and we don't want to
          // try to simplify those away.
          assert((L.contains(UserI) || isa<PHINode>(UserI)) &&
                 "Uses outside the loop should be PHI nodes due to LCSSA!");
          if (!IsFirstIteration && L.contains(UserI))
            ToSimplify->insert(UserI);
        }

        if (MSSAU)
          if (Instruction *SimpleI = dyn_cast_or_null<Instruction>(V))
            if (MemoryAccess *MA = MSSA->getMemoryAccess(&I))
              if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI))
                MA->replaceAllUsesWith(ReplacementMA);

        assert(I.use_empty() && "Should always have replaced all uses!");
        if (isInstructionTriviallyDead(&I, &TLI))
          DeadInsts.push_back(&I);
        ++NumSimplified;
        Changed = true;
      }
    }

    // Delete any dead instructions found thus far now that we've finished an
    // iteration over all instructions in all the loop blocks.
    if (!DeadInsts.empty()) {
      Changed = true;
      RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU);
    }

    if (MSSAU && VerifyMemorySSA)
      MSSA->verifyMemorySSA();

    // If we never found a PHI that needs to be simplified in the next
    // iteration, we're done.
    if (Next->empty())
      break;

    // Otherwise, put the next set in place for the next iteration and reset it
    // and the visited PHIs for that iteration.
    std::swap(Next, ToSimplify);
    Next->clear();
    VisitedPHIs.clear();
    DeadInsts.clear();
  }

  return Changed;
}
Example #3
0
 TestAnalyses(MemorySSATest &Test)
     : DT(*Test.F), AC(*Test.F), AA(Test.TLI),
       BAA(Test.DL, Test.TLI, AC, &DT), MSSA(*Test.F) {
   AA.addAAResult(BAA);
   Walker.reset(MSSA.buildMemorySSA(&AA, &DT));
 }