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)); } } }
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; } } } }
/** * 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; }