Пример #1
0
/// compile_right - Emit code for '>'                                                                               
void BrainFTraceRecorder::compile_right(BrainFTraceNode *node,
                                        IRBuilder<>& builder) {
  Value *OldPtr = DataPtr;
  DataPtr = builder.CreateConstInBoundsGEP1_32(DataPtr, 1);
  if (node->left != (BrainFTraceNode*)~0ULL)
    compile_opcode(node->left, builder);
  else {
    HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock());
    builder.CreateBr(Header);
  }
  DataPtr = OldPtr;
}
Пример #2
0
/// compile_if - Emit code for '['
void BrainFTraceRecorder::compile_if(BrainFTraceNode *node,
                                     IRBuilder<>& builder) {
  BasicBlock *ZeroChild = 0;
  BasicBlock *NonZeroChild = 0;
  BasicBlock *Parent = builder.GetInsertBlock();
  
  LLVMContext &Context = Header->getContext();
  
  // If both directions of the branch go back to the trace-head, just
  // jump there directly.
  if (node->left == (BrainFTraceNode*)~0ULL &&
      node->right == (BrainFTraceNode*)~0ULL) {
    HeaderPHI->addIncoming(DataPtr, builder.GetInsertBlock());
    builder.CreateBr(Header);
    return;
  }
  
  // Otherwise, there are two cases to handle for each direction:
  //   ~0ULL - A branch back to the trace head
  //   0 - A branch out of the trace
  //   * - A branch to a node we haven't compiled yet.
  // Go ahead and generate code for both targets.
  
  if (node->left == (BrainFTraceNode*)~0ULL) {
    NonZeroChild = Header;
    HeaderPHI->addIncoming(DataPtr, Parent);
  } else if (node->left == 0) {
    NonZeroChild = BasicBlock::Create(Context,
                                   "exit_left_"+utostr(node->pc),
                                   Header->getParent());
    builder.SetInsertPoint(NonZeroChild);
    
    // Set the extension leaf, which is a pointer to the leaf of the trace
    // tree from which we are side exiting.
    ConstantInt *ExtLeaf = ConstantInt::get(int_type, (intptr_t)node);
    builder.CreateStore(ExtLeaf, ext_leaf);
    
    ConstantInt *NewPc = ConstantInt::get(int_type, node->pc+1);
    Value *BytecodeIndex =
      builder.CreateConstInBoundsGEP1_32(bytecode_array, node->pc+1);
    Value *Target = builder.CreateLoad(BytecodeIndex);
    CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr));
    Call->setTailCall();
    builder.CreateRetVoid();
  } else {
    NonZeroChild = BasicBlock::Create(Context, 
                                      utostr(node->left->pc), 
                                      Header->getParent());
    builder.SetInsertPoint(NonZeroChild);
    compile_opcode(node->left, builder);
  }
  
  if (node->right == (BrainFTraceNode*)~0ULL) {
    ZeroChild = Header;
    HeaderPHI->addIncoming(DataPtr, Parent);
  } else if (node->right == 0) {
    ZeroChild = BasicBlock::Create(Context,
                                   "exit_right_"+utostr(node->pc),
                                   Header->getParent());
    builder.SetInsertPoint(ZeroChild);
    
    // Set the extension leaf, which is a pointer to the leaf of the trace
    // tree from which we are side exiting.
    ConstantInt *ExtLeaf = ConstantInt::get(int_type, (intptr_t)node);
    builder.CreateStore(ExtLeaf, ext_leaf);
    
    ConstantInt *NewPc = ConstantInt::get(int_type, JumpMap[node->pc]+1);
    Value *BytecodeIndex =
      builder.CreateConstInBoundsGEP1_32(bytecode_array, JumpMap[node->pc]+1);
    Value *Target = builder.CreateLoad(BytecodeIndex);
    CallInst *Call =cast<CallInst>(builder.CreateCall2(Target, NewPc, DataPtr));
    Call->setTailCall();
    builder.CreateRetVoid();
  } else {
    ZeroChild = BasicBlock::Create(Context, 
                                      utostr(node->right->pc), 
                                      Header->getParent());
    builder.SetInsertPoint(ZeroChild);
    compile_opcode(node->right, builder);
  }
  
  // Generate the test and branch to select between the targets.
  builder.SetInsertPoint(Parent);
  Value *Loaded = builder.CreateLoad(DataPtr);
  Value *Cmp = builder.CreateICmpEQ(Loaded, 
                                       ConstantInt::get(Loaded->getType(), 0));
  builder.CreateCondBr(Cmp, ZeroChild, NonZeroChild);
}