void ArrayProducerAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const
    {
      if ( moduleBuilder.haveCompiledToModule( getCodeName() ) )
        return;
        
      RC::Handle<Context> context = moduleBuilder.getContext();
      
      m_elementAdapter->llvmCompileToModule( moduleBuilder );
      m_elementVariableArrayAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter();
      booleanAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter();
      sizeAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter();
      stringAdapter->llvmCompileToModule( moduleBuilder );
      RC::ConstHandle<ConstStringAdapter> constStringAdapter = getManager()->getConstStringAdapter();
      constStringAdapter->llvmCompileToModule( moduleBuilder );      
            
      static const bool buildFunctions = true;
      
      {
        ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost );
        if ( buildFunctions )
        {
          llvm::Value *stringLValue = functionBuilder[0];
          BasicBlockBuilder basicBlockBuilder( functionBuilder );
          
          basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
          std::string name = getUserName();
          ExprValue exprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( basicBlockBuilder, name.data(), name.length() ) );
          llvm::Value *stringRValue = stringAdapter->llvmCast( basicBlockBuilder, exprValue );
          stringAdapter->llvmAssign( basicBlockBuilder, stringLValue, stringRValue );
          stringAdapter->llvmDispose( basicBlockBuilder, stringRValue );
          basicBlockBuilder->CreateRetVoid();
        }
      }
   
      {
        ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost );
        if ( buildFunctions )
        {
          llvm::Value *booleanLValue = functionBuilder[0];
          llvm::Value *rValue = functionBuilder[1];
          BasicBlockBuilder basicBlockBuilder( functionBuilder );
          basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
          llvm::Value *arrayProducerRValue = basicBlockBuilder->CreateLoad( rValue );
          basicBlockBuilder->CreateStore(
            basicBlockBuilder->CreateIsNotNull( arrayProducerRValue ),
            booleanLValue
            );
          basicBlockBuilder->CreateRetVoid();
        }
      }

      {
        MethodBuilder functionBuilder( moduleBuilder, sizeAdapter, this, USAGE_RVALUE, "getCount" );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          basicBlockBuilder->CreateRet(
            llvmGetCount( basicBlockBuilder, rValue )
            );
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder,
          m_elementVariableArrayAdapter,
          this, USAGE_RVALUE,
          "produce"
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          llvmProduce0( basicBlockBuilder, rValue, functionBuilder.getScope().llvmGetReturnLValue() );
          basicBlockBuilder->CreateRetVoid();
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder, m_elementAdapter,
          this, USAGE_RVALUE,
          "produce",
          "index", sizeAdapter, USAGE_RVALUE
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];
          llvm::Value *indexRValue = functionBuilder[1];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          CG::FunctionScope &functionScope = functionBuilder.getScope();
          functionScope.llvmPrepareReturnLValue( basicBlockBuilder );
          llvmProduce1( basicBlockBuilder, rValue, indexRValue, functionScope.llvmGetReturnLValue() );
          if ( functionScope.getReturnInfo().usesReturnLValue() )
            basicBlockBuilder->CreateRetVoid();
          else
            basicBlockBuilder->CreateRet( basicBlockBuilder->CreateLoad( functionScope.llvmGetReturnLValue() ) );
        }
      }

      {
        MethodBuilder functionBuilder(
          moduleBuilder, m_elementVariableArrayAdapter,
          this, USAGE_RVALUE,
          "produce",
          "index", sizeAdapter, USAGE_RVALUE,
          "count", sizeAdapter, USAGE_RVALUE
          );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];
          llvm::Value *indexRValue = functionBuilder[1];
          llvm::Value *countRValue = functionBuilder[2];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );
          llvmProduce2( basicBlockBuilder, rValue, indexRValue, countRValue, functionBuilder.getScope().llvmGetReturnLValue() );
          basicBlockBuilder->CreateRetVoid();
        }
      }
      
      {
        MethodBuilder functionBuilder( moduleBuilder, 0, this, USAGE_RVALUE, "flush" );
        if ( buildFunctions )
        {
          BasicBlockBuilder basicBlockBuilder( functionBuilder );

          llvm::Value *rValue = functionBuilder[0];

          llvm::BasicBlock *entryBB = basicBlockBuilder.getFunctionBuilder().createBasicBlock( "entry" );
          
          basicBlockBuilder->SetInsertPoint( entryBB );

          llvmFlush( basicBlockBuilder, rValue );
          basicBlockBuilder->CreateRetVoid();
        }
      }
    }
Пример #2
0
 void OpaqueAdapter::llvmCompileToModule( ModuleBuilder &moduleBuilder ) const
 {
   if ( moduleBuilder.haveCompiledToModule( getCodeName() ) )
     return;
   
   RC::Handle<Context> context = moduleBuilder.getContext();
   
   RC::ConstHandle<BooleanAdapter> booleanAdapter = getManager()->getBooleanAdapter();
   booleanAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<SizeAdapter> sizeAdapter = getManager()->getSizeAdapter();
   sizeAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<StringAdapter> stringAdapter = getManager()->getStringAdapter();
   stringAdapter->llvmCompileToModule( moduleBuilder );
   RC::ConstHandle<OpaqueAdapter> dataAdapter = getManager()->getDataAdapter();
   dataAdapter->llvmCompileToModule( moduleBuilder );
   
   static const bool buildFunctions = true;
   
   {
     ConstructorBuilder functionBuilder( moduleBuilder, booleanAdapter, this, ConstructorBuilder::HighCost );
     if ( buildFunctions )
     {
       llvm::Value *booleanLValue = functionBuilder[0];
       llvm::Value *opaqueRValue = functionBuilder[1];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *booleanRValue = basicBlockBuilder->CreateIsNotNull( opaqueRValue );
       booleanAdapter->llvmAssign( basicBlockBuilder, booleanLValue, booleanRValue );
       basicBlockBuilder->CreateRetVoid();
     }
   }
   
   {
     ConstructorBuilder functionBuilder( moduleBuilder, stringAdapter, this, ConstructorBuilder::HighCost );
     if ( buildFunctions )
     {
       llvm::Value *stringLValue = functionBuilder[0];
       llvm::Value *opaqueRValue = functionBuilder[1];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *opaqueLValue = llvmRValueToLValue( basicBlockBuilder, opaqueRValue );
       stringAdapter->llvmCallCast( basicBlockBuilder, this, opaqueLValue, stringLValue );
       basicBlockBuilder->CreateRetVoid();
     }
   }
   
   {
     MethodBuilder functionBuilder(
       moduleBuilder,
       sizeAdapter,
       this, USAGE_RVALUE,
       "dataSize"
       );
     if ( buildFunctions )
     {
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       llvm::Value *dataSizeRValue = sizeAdapter->llvmConst( context, getDesc()->getAllocSize() );
       basicBlockBuilder->CreateRet( dataSizeRValue );
     }
   }
   
   {
     MethodBuilder functionBuilder(
       moduleBuilder,
       dataAdapter,
       this, USAGE_LVALUE,
       "data"
       );
     if ( buildFunctions )
     {
       llvm::Value *thisLValue = functionBuilder[0];
       BasicBlockBuilder basicBlockBuilder( functionBuilder );
       basicBlockBuilder->SetInsertPoint( functionBuilder.createBasicBlock( "entry" ) );
       basicBlockBuilder->CreateRet( basicBlockBuilder->CreatePointerCast( thisLValue, dataAdapter->llvmRType( context ) ) );
     }
   }
 }