示例#1
0
 void ReturnStatement::llvmCompileToBuilder( CG::BasicBlockBuilder &basicBlockBuilder, CG::Diagnostics &diagnostics ) const
 {
   try
   {
     CG::ReturnInfo const &returnInfo = basicBlockBuilder.getFunctionBuilder().getScope().getReturnInfo();
     if ( basicBlockBuilder->GetInsertBlock()->getTerminator() )
       throw CG::Error( getLocation(), "unreachable code" );
     CG::ExprValue returnExprValue( CG::ExprValue( basicBlockBuilder.getContext() ) );
     if ( m_expr )
     {
       if ( !returnInfo )
         throw CG::Error( getLocation(), "functions with no return types do not return values" );
       returnExprValue = m_expr->buildExprValue( basicBlockBuilder, CG::USAGE_RVALUE, "cannot be assigned to" );
     }
     else
     {
       if ( returnInfo )
         throw CG::Error( getLocation(), "function must return a value" );
     }
     basicBlockBuilder.getScope().llvmReturn( basicBlockBuilder, returnExprValue );
   }
   catch ( Exception e )
   {
     addError( diagnostics, e );
   }
 }
示例#2
0
    void ContainerLoop::llvmCompileToBuilder( CG::BasicBlockBuilder &parentBasicBlockBuilder, CG::Diagnostics &diagnostics ) const
    {
      try
      {
        CG::BasicBlockBuilder &basicBlockBuilder = parentBasicBlockBuilder;
        
        RC::Handle<CG::Context> context = parentBasicBlockBuilder.getContext();
        
        CG::ExprValue dictExprValue = m_dictExpr->buildExprValue( parentBasicBlockBuilder, CG::USAGE_UNSPECIFIED, "" );
        RC::ConstHandle<CG::Adapter> adapter = dictExprValue.getAdapter();
        if ( !RT::isDict( adapter->getType() ) )
          throw CG::Error( m_dictExpr->getLocation(), "must be a dictionary" );
        RC::ConstHandle<CG::DictAdapter> dictAdapter = RC::ConstHandle<CG::DictAdapter>::StaticCast( adapter );
        RC::ConstHandle<CG::ComparableAdapter> keyAdapter = dictAdapter->getKeyAdapter();
        RC::ConstHandle<CG::Adapter> valueAdapter = dictAdapter->getValueAdapter();

        llvm::Type *nodePtrType = dictAdapter->getLLVMNodePtrType( context );
        llvm::Instruction *nodePtrPtr = new llvm::AllocaInst( nodePtrType );
        nodePtrPtr->setName( m_keyName );
        
        // [pzion 20111019] We allocate variables at the top of the function
        CG::FunctionBuilder &functionBuilder = parentBasicBlockBuilder.getFunctionBuilder();
        llvm::BasicBlock &entryBB = functionBuilder->getEntryBlock();
        llvm::BasicBlock::iterator it = entryBB.begin();
        while ( it != entryBB.end() )
        {
          if ( !llvm::isa<llvm::AllocaInst>(*it) )
            break;
          ++it;
        }
        entryBB.getInstList().insert( it, nodePtrPtr );
        
        llvm::Value *bitsPtr = basicBlockBuilder->CreateLoad( dictExprValue.getValue() );
        
        llvm::BasicBlock *startBB = parentBasicBlockBuilder.getFunctionBuilder().createBasicBlock( "containerLoopStart" );
        llvm::BasicBlock *checkBB = parentBasicBlockBuilder.getFunctionBuilder().createBasicBlock( "containerLoopCheck" );
        llvm::BasicBlock *bodyBB = parentBasicBlockBuilder.getFunctionBuilder().createBasicBlock( "containerLoopBody" );
        llvm::BasicBlock *stepBB = parentBasicBlockBuilder.getFunctionBuilder().createBasicBlock( "containerLoopStep" );
        llvm::BasicBlock *endBB = parentBasicBlockBuilder.getFunctionBuilder().createBasicBlock( "containerLoopEnd" );
        
        basicBlockBuilder->CreateCondBr(
          basicBlockBuilder->CreateIsNotNull( bitsPtr ),
          startBB,
          endBB
          );
        
        // [pzion 20111019] Load bits->firstNode into llvmNodePtrPtr
        basicBlockBuilder->SetInsertPoint( startBB );
        llvm::Value *firstNodePtrPtr = basicBlockBuilder->CreateStructGEP( bitsPtr, 3 );
        llvm::Value *firstNodePtr = basicBlockBuilder->CreateLoad( firstNodePtrPtr );
        basicBlockBuilder->CreateStore( firstNodePtr, nodePtrPtr );
        basicBlockBuilder->CreateBr( checkBB );

        basicBlockBuilder->SetInsertPoint( checkBB );
        llvm::Value *nodePtr = basicBlockBuilder->CreateLoad( nodePtrPtr );
        basicBlockBuilder->CreateCondBr(
          basicBlockBuilder->CreateIsNull( nodePtr ),
          endBB,
          bodyBB
          );

        basicBlockBuilder->SetInsertPoint( bodyBB );
        llvm::Value *bitsNextNodePtrPtr = basicBlockBuilder->CreateStructGEP( nodePtr, 1 );
        llvm::Value *bitsNextNodePtr = basicBlockBuilder->CreatePointerCast(
          basicBlockBuilder->CreateLoad( bitsNextNodePtrPtr ),
          nodePtrType
          );
        {
          CG::LoopScope loopScope( parentBasicBlockBuilder.getScope(), endBB, stepBB );
          llvm::Value *keyLValue = basicBlockBuilder->CreatePointerCast(
            basicBlockBuilder->CreateStructGEP( nodePtr, 5 ),
            keyAdapter->llvmLType( context )
            );
          llvm::Value *keyRValue = keyAdapter->llvmLValueToRValue( basicBlockBuilder, keyLValue );
          loopScope.put( m_keyName, CG::ParameterSymbol::Create( CG::ExprValue( keyAdapter, CG::USAGE_RVALUE, context, keyRValue ) ) );
          llvm::Value *valueRValue = 0;
          if ( m_valueName.length() > 0 )
          {
            llvm::Value *valueLValue = basicBlockBuilder->CreatePointerCast(
              basicBlockBuilder->CreateConstGEP2_32(
                basicBlockBuilder->CreateStructGEP( nodePtr, 5 ),
                0,
                keyAdapter->getImpl()->getAllocSize()
                ),
              valueAdapter->llvmLType( context )
              );
            switch ( dictExprValue.getUsage() )
            {
              case CG::USAGE_RVALUE:
              {
                valueRValue = valueAdapter->llvmLValueToRValue( basicBlockBuilder, valueLValue );
                loopScope.put( m_valueName, CG::ParameterSymbol::Create( CG::ExprValue( valueAdapter, CG::USAGE_RVALUE, context, valueRValue ) ) );
              }
              break;
              
              case CG::USAGE_LVALUE:
              {
                loopScope.put( m_valueName, CG::ParameterSymbol::Create( CG::ExprValue( valueAdapter, CG::USAGE_LVALUE, context, valueLValue ) ) );
              }
              break;
              
              default:
                FABRIC_ASSERT(false);
                break;
            }
          }
          CG::BasicBlockBuilder loopBasicBlockBuilder( parentBasicBlockBuilder, loopScope );
          m_body->llvmCompileToBuilder( loopBasicBlockBuilder, diagnostics );
          loopScope.llvmUnwind( loopBasicBlockBuilder );
        }
        basicBlockBuilder->CreateBr( stepBB );

        basicBlockBuilder->SetInsertPoint( stepBB );
        basicBlockBuilder->CreateStore( bitsNextNodePtr, nodePtrPtr );
        basicBlockBuilder->CreateBr( checkBB );
        
        basicBlockBuilder->SetInsertPoint( endBB );
      }
      catch ( CG::Error e )
      {
        addError( diagnostics, e );
      }
      catch ( Exception e )
      {
        addError( diagnostics, e );
      }
    }