Ejemplo n.º 1
0
 BasicBlockBuilder::BasicBlockBuilder( BasicBlockBuilder &parentBasicBlockBuilder, Scope &scope )
   : m_functionBuilder( parentBasicBlockBuilder.getFunctionBuilder() )
   , m_parentBasicBlockBuilder( &parentBasicBlockBuilder )
   , m_irBuilder( parentBasicBlockBuilder.getContext()->getLLVMContext() )
   , m_scope( scope )     
 {
   m_irBuilder.SetInsertPoint( parentBasicBlockBuilder.m_irBuilder.GetInsertBlock() );
 }
Ejemplo n.º 2
0
 void ArrayProducerAdapter::llvmInit( BasicBlockBuilder &basicBlockBuilder, llvm::Value *lValue ) const
 {
   llvm::PointerType *rawType = static_cast<llvm::PointerType *>( llvmRawType( basicBlockBuilder.getContext() ) );
   basicBlockBuilder->CreateStore(
     llvm::ConstantPointerNull::get( rawType ),
     lValue
     );
 }
Ejemplo n.º 3
0
 void ArrayProducerAdapter::llvmDefaultAssign( BasicBlockBuilder &basicBlockBuilder, llvm::Value *dstLValue, llvm::Value *srcRValue ) const
 {
   RC::Handle<Context> context = basicBlockBuilder.getContext();
   std::vector<llvm::Type *> argTypes;
   argTypes.push_back( llvmRType( context ) );
   argTypes.push_back( llvmLType( context ) );
   llvm::FunctionType *funcType = llvm::FunctionType::get( llvm::Type::getVoidTy( context->getLLVMContext() ), argTypes, false );
   llvm::Constant *func = basicBlockBuilder.getModuleBuilder()->getOrInsertFunction( "__"+getCodeName()+"__DefaultAssign", funcType ); 
   basicBlockBuilder->CreateCall2( func, srcRValue, dstLValue );
 }
Ejemplo n.º 4
0
 void StructAdapter::llvmDefaultAssign( BasicBlockBuilder &basicBlockBuilder, llvm::Value *dstLValue, llvm::Value *srcRValue ) const
 {
   if ( !m_isShallow )
   {
     InternalFunctionBuilder functionBuilder(
       basicBlockBuilder.getModuleBuilder(),
       0, "__" + getCodeName() + "__DefaultAssign",
       "dst", this, USAGE_LVALUE,
       "src", this, USAGE_RVALUE,
       0
       );
     basicBlockBuilder->CreateCall2( functionBuilder.getLLVMFunction(), dstLValue, srcRValue );
   }
   else basicBlockBuilder->CreateStore( basicBlockBuilder->CreateLoad( srcRValue ), dstLValue );
 }
Ejemplo n.º 5
0
    void ArrayAdapter::llvmThrowOutOfRangeException(
      BasicBlockBuilder &basicBlockBuilder,
      llvm::Value *itemDescRValue,
      llvm::Value *indexRValue,
      llvm::Value *sizeRValue,
      llvm::Value *errorDescRValue
      ) const
    {
      RC::Handle<Context> context = basicBlockBuilder.getContext();
      RC::ConstHandle<SizeAdapter> sizeAdapter = basicBlockBuilder.getManager()->getSizeAdapter();
      RC::ConstHandle<StringAdapter> stringAdapter = basicBlockBuilder.getManager()->getStringAdapter();
      RC::ConstHandle<ConstStringAdapter> constStringAdapter = basicBlockBuilder.getManager()->getConstStringAdapter();

      std::vector<llvm::Type const *> argTypes;
      argTypes.push_back( constStringAdapter->llvmRType( context ) );
      argTypes.push_back( sizeAdapter->llvmRType( context ) );
      argTypes.push_back( sizeAdapter->llvmRType( context ) );
      argTypes.push_back( constStringAdapter->llvmRType( context ) );
      llvm::FunctionType const *funcType = llvm::FunctionType::get( basicBlockBuilder->getVoidTy(), argTypes, false );
      
      llvm::AttributeWithIndex AWI[1];
      AWI[0] = llvm::AttributeWithIndex::get( ~0u, 0 /*llvm::Attribute::InlineHint | llvm::Attribute::NoUnwind*/ );
      llvm::AttrListPtr attrListPtr = llvm::AttrListPtr::get( AWI, 1 );

      std::string name = "__ThrowOutOfRangeException";
      llvm::Function *func = llvm::cast<llvm::Function>( basicBlockBuilder.getModuleBuilder()->getFunction( name ) );
      if ( !func )
      {
        ModuleBuilder &mb = basicBlockBuilder.getModuleBuilder();
        
        func = llvm::cast<llvm::Function>( mb->getOrInsertFunction( name, funcType, attrListPtr ) ); 
        func->setLinkage( llvm::GlobalValue::PrivateLinkage );
        
        FunctionBuilder fb( mb, funcType, func );
        llvm::Argument *itemRValue = fb[0];
        itemRValue->setName( "itemRValue" );
        itemRValue->addAttr( llvm::Attribute::NoCapture );
        llvm::Argument *indexRValue = fb[1];
        indexRValue->setName( "indexRValue" );
        llvm::Argument *sizeRValue = fb[2];
        sizeRValue->setName( "sizeRValue" );
        llvm::Argument *errorDescRValue = fb[3];
        errorDescRValue->setName( "errorDescRValue" );
        errorDescRValue->addAttr( llvm::Attribute::NoCapture );
        
        BasicBlockBuilder bbb( fb );
        llvm::BasicBlock *entryBB = fb.createBasicBlock( "entry" );
        bbb->SetInsertPoint( entryBB );

        llvm::Value *errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3LValue;
        {
          Scope subScope( bbb.getScope() );
          BasicBlockBuilder subBasicBlockBuilder( bbb, subScope );

          llvm::BasicBlock *haveErrorDescBB = fb.createBasicBlock( "haveErrorDescBB" );
          llvm::BasicBlock *noErrorDescBB = fb.createBasicBlock( "noErrorDescBB" );
          llvm::BasicBlock *goBB = fb.createBasicBlock( "goBB" );

          subBasicBlockBuilder->CreateCondBr(
            subBasicBlockBuilder->CreateIsNotNull( errorDescRValue ),
            haveErrorDescBB,
            noErrorDescBB
            );
            
          subBasicBlockBuilder->SetInsertPoint( haveErrorDescBB );
          llvm::Value *haveErrorDescConstStringRValue = errorDescRValue;
          subBasicBlockBuilder->CreateBr( goBB );
            
          subBasicBlockBuilder->SetInsertPoint( noErrorDescBB );
          llvm::Value *noErrorDescConstStringRValue = constStringAdapter->llvmConst( subBasicBlockBuilder, "KL" );
          subBasicBlockBuilder->CreateBr( goBB );

          subBasicBlockBuilder->SetInsertPoint( goBB );
          llvm::PHINode *errorDescConstStringRValue = subBasicBlockBuilder->CreatePHI( haveErrorDescConstStringRValue->getType(), "errorDescConstStringRValue" );
          errorDescConstStringRValue->addIncoming( haveErrorDescConstStringRValue, haveErrorDescBB );
          errorDescConstStringRValue->addIncoming( noErrorDescConstStringRValue, noErrorDescBB );

          llvm::Value *errorMsg0RValue = stringAdapter->llvmCast(
            subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, errorDescConstStringRValue )
            );
          
          llvm::Value *errorMsgARValue = stringAdapter->llvmCast( subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( subBasicBlockBuilder, ": " ) )
            );
          
          llvm::Value *errorMsgALValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsgA" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsgALValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            errorMsg0RValue,
            errorMsgARValue,
            errorMsgALValue
            );
          
          llvm::Value *errorMsgBRValue = stringAdapter->llvmCast( subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, itemRValue )
            );
          
          llvm::Value *errorMsgBLValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsgB" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsgBLValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsgALValue ),
            errorMsgBRValue,
            errorMsgBLValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsgALValue );
          
          llvm::Value *errorMsgCRValue = stringAdapter->llvmCast( subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( subBasicBlockBuilder, " (" ) )
            );
          
          llvm::Value *errorMsgCLValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsgC" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsgCLValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsgBLValue ),
            errorMsgCRValue,
            errorMsgCLValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsgBLValue );
          
          llvm::Value *indexStringRValue = stringAdapter->llvmCast(
            subBasicBlockBuilder,
            ExprValue( sizeAdapter, USAGE_RVALUE, context, indexRValue )
            );
            
          llvm::Value *errorMsg1PlusIndexLValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsg1PlusIndex" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsg1PlusIndexLValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsgCLValue ),
            indexStringRValue,
            errorMsg1PlusIndexLValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsgCLValue );
          
          llvm::Value *errorMsg2RValue = stringAdapter->llvmCast(
            subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( subBasicBlockBuilder, ") out of range (" ) )
            );
            
          llvm::Value *errorMsg1PlusIndexPlusErrorMsg2LValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsg1PlusIndexPlusErrorMsg2" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2LValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsg1PlusIndexLValue ),
            errorMsg2RValue,
            errorMsg1PlusIndexPlusErrorMsg2LValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsg1PlusIndexLValue );

          llvm::Value *sizeStringRValue = stringAdapter->llvmCast(
            subBasicBlockBuilder,
            ExprValue( sizeAdapter, USAGE_RVALUE, context, sizeRValue )
            );
            
          llvm::Value *errorMsg1PlusIndexPlusErrorMsg2PlusSizeLValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsg1PlusIndexPlusErrorMsg2PlusSize" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2PlusSizeLValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2LValue ),
            sizeStringRValue,
            errorMsg1PlusIndexPlusErrorMsg2PlusSizeLValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2LValue );

          llvm::Value *errorMsg3RValue = stringAdapter->llvmCast(
            subBasicBlockBuilder,
            ExprValue( constStringAdapter, USAGE_RVALUE, context, constStringAdapter->llvmConst( subBasicBlockBuilder, ")" ) )
            );
            
          errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3LValue = stringAdapter->llvmAlloca( subBasicBlockBuilder, "errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3" );
          stringAdapter->llvmInit( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3LValue );
          stringAdapter->llvmCallConcat(
            subBasicBlockBuilder,
            stringAdapter->llvmLValueToRValue( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2PlusSizeLValue ),
            errorMsg3RValue,
            errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3LValue
            );
          stringAdapter->llvmDispose( subBasicBlockBuilder, errorMsg1PlusIndexPlusErrorMsg2PlusSizeLValue );
          
          subScope.llvmUnwind( subBasicBlockBuilder );
        }
        llvmThrowException( bbb, errorMsg1PlusIndexPlusErrorMsg2PlusSizePlusErrorMsg3LValue );
        bbb->CreateRetVoid();
      }
      
      std::vector<llvm::Value *> args;
      args.push_back( itemDescRValue );
      args.push_back( indexRValue );
      args.push_back( sizeRValue );
      args.push_back( errorDescRValue );
      basicBlockBuilder->CreateCall( func, args.begin(), args.end() );
    }
Ejemplo n.º 6
0
    ExprValue Function::llvmCreateCall( BasicBlockBuilder &basicBlockBuilder, std::vector<ExprValue> &args ) const
    {
      RC::Handle<Context> context = basicBlockBuilder.getContext();
      
      if ( m_params.size() != args.size() )
        throw Exception( "incorrect number of arguments (expected %u, actual %u)", (unsigned)m_params.size(), (unsigned)args.size() );

      for ( size_t i=0; i<args.size(); ++i )
      {
        FunctionParam const &param = m_params[i];
        ExprValue &arg = args[i];

        if( !arg.isValid() )
          throw Exception( "expression is invalid" );
        
        try
        {
          arg.castTo( basicBlockBuilder, param.getExprType() );
        }
        catch ( Exception e )
        {
          throw Exception( "argument %u ('%s'): %s", (unsigned)(i + 1), param.getName().c_str(), (const char*)e.getDesc() );
        }
      }

      llvm::Value *returnValue = 0;
      if ( m_returnInfo.usesReturnLValue() )
      {
        RC::ConstHandle<Adapter> returnAdapter = m_returnInfo.getAdapter();
        returnValue = returnAdapter->llvmAlloca( basicBlockBuilder, "resultLValue" );
        returnAdapter->llvmInit( basicBlockBuilder, returnValue );
        args.resize( args.size() + 1, ExprValue(context) );
        for ( size_t i=1; i<args.size(); ++i )
          args[args.size()-i] = args[args.size()-i-1];
        args[0] = ExprValue( returnAdapter, USAGE_LVALUE, context, returnValue );
        basicBlockBuilder.getScope().put( CG::VariableSymbol::Create( args[0] ) );
      }
      
      std::vector<llvm::Value *> argValues;
      for ( size_t i=0; i<args.size(); ++i )
        argValues.push_back( args[i].getValue() );
      /*
      llvm::BasicBlock *lpbb = basicBlockBuilder.getFunctionBuilder()->createBasicBlock( "lpbb" );
      llvm::BasicBlock *normalbb = basicBlockBuilder.getFunctionBuilder()->createBasicBlock( "normalbb" );

      llvm::Value *resultValue = basicBlockBuilder->CreateInvoke( m_llvmFunction, normalbb, lpbb, argValues );

      if( !m_returnInfo.usesReturnLValue() )
        returnValue = resultValue;

      basicBlockBuilder->SetInsertPoint( lpbb );
      basicBlockBuilder->CreateLandingPad();
      basicBlockBuilder->CreateBr( normalbb );

      basicBlockBuilder->SetInsertPoint( normalbb );
      */

      llvm::Value *resultValue = basicBlockBuilder->CreateCall( m_llvmFunction, argValues );
      if( !m_returnInfo.usesReturnLValue() )
        returnValue = resultValue;

      return CG::ExprValue( m_returnInfo.getExprType(), context, returnValue );
    }
Ejemplo n.º 7
0
 void OpaqueAdapter::llvmDefaultAssign( BasicBlockBuilder &basicBlockBuilder, llvm::Value *dstLValue, llvm::Value *srcRValue ) const
 {
   basicBlockBuilder->CreateStore( srcRValue, dstLValue );
 }