void ConstantInsertExtractElementIndex::findNonConstantInsertExtractElements(
    const BasicBlock &BB, Instructions &OutOfRangeConstantIndices,
    Instructions &NonConstantVectorIndices) const {
  for (BasicBlock::const_iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;
       ++BBI) {
    const Instruction *I = &*BBI;
    if (Value *Idx = getInsertExtractElementIdx(I)) {
      if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
        if (!CI->getValue().ult(vectorNumElements(I)))
          OutOfRangeConstantIndices.push_back(const_cast<Instruction *>(I));
      } else
        NonConstantVectorIndices.push_back(const_cast<Instruction *>(I));
    }
  }
}
Example #2
0
Instructions Bytecode::parser(const Tokens& tokens) const {
    Tokens tokens_group;
    // Abstract syntax tree.
    Instructions ast;
    int funcs = 0, params = 0, specs = 0;
    for (int i = 0; i < tokens.size(); i++) {
        if (tokens[i].type == DELIMITER) {
            checkFunctions(tokens_group[0], funcs);
            checkById(tokens_group[0].function_id, params, specs);
            Instruction inst =
                makeInstruction(params, specs, tokens_group);
            ast.push_back(inst);
            funcs = 0, params = 0, specs = 0;
            tokens_group.clear();
        } else {
            if (tokens[i].type == FUNCTION) {
                funcs++;
            } else if (tokens[i].type == PARAMETER) {
                params++;
            } else {
                specs++;
            }
            tokens_group.push_back(tokens[i]);
        }
    }
    return ast;
}
void AArch64AddressTypePromotion::mergeSExts(ValueToInsts &ValToSExtendedUses,
                                             SetOfInstructions &ToRemove) {
  DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();

  for (auto &Entry : ValToSExtendedUses) {
    Instructions &Insts = Entry.second;
    Instructions CurPts;
    for (Instruction *Inst : Insts) {
      if (ToRemove.count(Inst))
        continue;
      bool inserted = false;
      for (auto &Pt : CurPts) {
        if (DT.dominates(Inst, Pt)) {
          DEBUG(dbgs() << "Replace all uses of:\n" << *Pt << "\nwith:\n"
                       << *Inst << '\n');
          Pt->replaceAllUsesWith(Inst);
          ToRemove.insert(Pt);
          Pt = Inst;
          inserted = true;
          break;
        }
        if (!DT.dominates(Pt, Inst))
          // Give up if we need to merge in a common dominator as the
          // expermients show it is not profitable.
          continue;

        DEBUG(dbgs() << "Replace all uses of:\n" << *Inst << "\nwith:\n"
                     << *Pt << '\n');
        Inst->replaceAllUsesWith(Pt);
        ToRemove.insert(Inst);
        inserted = true;
        break;
      }
      if (!inserted)
        CurPts.push_back(Inst);
    }
  }
}
void AArch64AddressTypePromotion::analyzeSExtension(Instructions &SExtInsts) {
  DEBUG(dbgs() << "*** Analyze Sign Extensions ***\n");

  DenseMap<Value *, Instruction *> SeenChains;

  for (auto &BB : *Func) {
    for (auto &II : BB) {
      Instruction *SExt = &II;

      // Collect all sext operation per type.
      if (!isa<SExtInst>(SExt) || !shouldConsiderSExt(SExt))
        continue;

      DEBUG(dbgs() << "Found:\n" << (*SExt) << '\n');

      // Cases where we actually perform the optimization:
      // 1. SExt is used in a getelementptr with more than 2 operand =>
      //    likely we can merge some computation if they are done on 64 bits.
      // 2. The beginning of the SExt chain is SExt several time. =>
      //    code sharing is possible.

      bool insert = false;
      // #1.
      for (const User *U : SExt->users()) {
        const Instruction *Inst = dyn_cast<GetElementPtrInst>(U);
        if (Inst && Inst->getNumOperands() > 2) {
          DEBUG(dbgs() << "Interesting use in GetElementPtrInst\n" << *Inst
                       << '\n');
          insert = true;
          break;
        }
      }

      // #2.
      // Check the head of the chain.
      Instruction *Inst = SExt;
      Value *Last;
      do {
        int OpdIdx = 0;
        const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Inst);
        if (BinOp && isa<ConstantInt>(BinOp->getOperand(0)))
          OpdIdx = 1;
        Last = Inst->getOperand(OpdIdx);
        Inst = dyn_cast<Instruction>(Last);
      } while (Inst && canGetThrough(Inst) && shouldGetThrough(Inst));

      DEBUG(dbgs() << "Head of the chain:\n" << *Last << '\n');
      DenseMap<Value *, Instruction *>::iterator AlreadySeen =
          SeenChains.find(Last);
      if (insert || AlreadySeen != SeenChains.end()) {
        DEBUG(dbgs() << "Insert\n");
        SExtInsts.push_back(SExt);
        if (AlreadySeen != SeenChains.end() && AlreadySeen->second != nullptr) {
          DEBUG(dbgs() << "Insert chain member\n");
          SExtInsts.push_back(AlreadySeen->second);
          SeenChains[Last] = nullptr;
        }
      } else {
        DEBUG(dbgs() << "Record its chain membership\n");
        SeenChains[Last] = SExt;
      }
    }
  }
}
Example #5
0
/**
 * Compiles a brainfreeze program. It converts the program's
 * textual representation into a program containing only the
 * brainfreeze vm instructions.
 *
 * Additionally, it performs several compile time optimizations in order to
 * speed up execution time. These optimizations include pre-calculating
 * jump offsets and fusing sequential identical instructions.
 *
 * \return Returns true if the program was succesfully compiled, otherwise
 *         it will return false to indicate the presence of errors
 */
bool BFProgram::compile()
{
    Instructions temp;
    Instruction  last = Instruction( OP_EOF, 0 );
    std::stack<int> jumps;  // record positions for [

    //
    // Scan the code string. Replace each BF instruction 
    // with its symbolic equivilant.
    //
    int icount = 0;
    for( std::string::iterator itr  = m_codestr.begin();
                               itr != m_codestr.end();
                             ++itr )
    {
        if( BF::isInstruction( *itr ) )
        {
            // Convert the character into an instruction
            Instruction instr = BF::convert( *itr );

            //
            // Is this a jump instruction?
            //
            if ( instr.opcode() == OP_JMP_FWD )
            {
                // This is a forward jump. Record its position
                jumps.push(icount);
            }
            else if ( instr.opcode() == OP_JMP_BAC )
            {
                // This is a backward jump. Pop the corresponding
                // forward jump marker off the stack, and update both
                // of the instructions with the location of their 
                // corresponding targets.
                int backpos = jumps.top(); jumps.pop();
                int dist    = icount - backpos;

                assert( dist > 0 );

                // Update the [ character
                temp[backpos].setParam( dist );

                // Update the ] (current) character
                instr.setParam( dist );
            }

            //
            // Was the last character a repeat of +, -, >, <
            //
            if ( ( instr.opcode() == last.opcode() ) &&
                 ( instr.opcode() == OP_PTR_INC || 
                   instr.opcode() == OP_PTR_DEC ||
                   instr.opcode() == OP_MEM_INC ||
                   instr.opcode() == OP_MEM_DEC ) )
            {
                // Get the last character, and update its occurrence
                temp[icount-1].setParam( temp[icount-1].param() + 1 );
            }
            else
            {
                // Add the instruction to the instruction stream
                temp.push_back( instr );

                // Remember last instruction
                last = instr;

                // Increment instruction counter
                icount += 1;
            }

            // Remember the last instruction
            last = instr;
        }
    }

    // Verify the jump stack is empty. If not, then there is a
    // mismatched jump somewhere!
    if (! jumps.empty() )
    {
        raiseError( "Mismatched jump detected when compiling" );
        return false;
    }

    // Insert end of program instruction
    temp.push_back( Instruction( OP_EOF, 0 ) );
    
    // Save it to m_instructions
    m_instructions.swap( temp );
    m_ip = m_instructions.begin();

    return true;
}