<commit_before>#import "TQNodeVariable.h"
#import "../TQProgram.h"
#import "../TQDebug.h"
#import <llvm/IRBuilder.h>

using namespace llvm;

@interface TQNodeVariable (Private)
- (TQNodeVariable *)_getExistingIdenticalInBlock:(TQNodeBlock *)aBlock;
- (const char *)_llvmRegisterName:(NSString *)subname;
@end

@implementation TQNodeVariable
@synthesize name=_name, alloca=_alloca, forwarding=_forwarding;

+ (TQNodeVariable *)nodeWithName:(NSString *)aName
{
    return [[[self alloc] initWithName:aName] autorelease];
}

- (id)initWithName:(NSString *)aName
{
    if(!(self = [super init]))
        return nil;

    _name = [aName retain];

    return self;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"<var@ %@>", _name ? _name : @"unnamed"];
}

- (NSUInteger)hash
{
    return [_name hash];
}

- (BOOL)isEqual:(id)aObj
{
    if([aObj isKindOfClass:[TQNodeVariable class]] && [[(TQNodeVariable *)aObj name] isEqualToString:_name])
        return YES;
    else
        return NO;
}
- (TQNode *)referencesNode:(TQNode *)aNode
{
    return [aNode isEqual:self] ? self : nil;
}


- (void)dealloc
{
    [_name release];
    [super dealloc];
}

- (llvm::Value *)_getForwardingInProgram:(TQProgram *)aProgram block:(TQNodeBlock *)aBlock
{
    TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
    if(existingVar)
        return [existingVar _getForwardingInProgram:aProgram block:aBlock];

    IRBuilder<> *builder = aBlock.builder;
    Value *forwarding;
    forwarding = builder->CreateLoad(builder->CreateStructGEP(_alloca, 1), [self _llvmRegisterName:@"forwardingPtr"]);
    forwarding = builder->CreateBitCast(forwarding, PointerType::getUnqual([self captureStructTypeInProgram:aProgram]), [self _llvmRegisterName:@"forwarding"]);

    return builder->CreateLoad(builder->CreateStructGEP(forwarding, 4));
}

- (llvm::Type *)captureStructTypeInProgram:(TQProgram *)aProgram
{
    static Type *captureType = NULL;
    if(captureType)
        return captureType;

    Type *i8PtrTy = aProgram.llInt8PtrTy;
    Type *intTy   = aProgram.llIntTy;

    captureType = StructType::create("struct._block_byref",
                                     i8PtrTy, // isa
                                     i8PtrTy, // forwarding
                                     intTy,   // flags (refcount)
                                     intTy,   // size ( = sizeof(id))
                                     i8PtrTy, // Captured variable (id)
                                     NULL);
    return captureType;
}

- (const char *)_llvmRegisterName:(NSString *)subname
{
    return _name ? [[NSString stringWithFormat:@"%@.%@", _name, subname] UTF8String] : "";
}

- (llvm::Value *)createStorageInProgram:(TQProgram *)aProgram
                                 block:(TQNodeBlock *)aBlock
                                 error:(NSError **)aoError
{
    if(_alloca)
        return _alloca;

    IRBuilder<> *builder = aBlock.builder;
    TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
    if(existingVar) {
        if(![existingVar generateCodeInProgram:aProgram block:aBlock error:aoError])
            return NULL;
        _alloca = existingVar.alloca;

        return _alloca;
    }
    Type *intTy   = aProgram.llIntTy;
    Type *i8PtrTy = aProgram.llInt8PtrTy;

    Type *byRefType = [self captureStructTypeInProgram:aProgram];
    IRBuilder<> entryBuilder(&aBlock.function->getEntryBlock(), aBlock.function->getEntryBlock().begin());
    AllocaInst *alloca = entryBuilder.CreateAlloca(byRefType, 0, [self _llvmRegisterName:@"alloca"]);

    // Initialize the variable to nil
    builder->CreateStore(builder->CreateBitCast(alloca, i8PtrTy),        builder->CreateStructGEP(alloca, 1, [self
    _llvmRegisterName:@"forwardingAssign"]));
    builder->CreateStore(ConstantInt::get(intTy, 0), builder->CreateStructGEP(alloca, 2, [self _llvmRegisterName:@"flags"]));
    Constant *size = ConstantExpr::getTruncOrBitCast(ConstantExpr::getSizeOf(byRefType), intTy);
    builder->CreateStore(size,                                           builder->CreateStructGEP(alloca, 3, [self _llvmRegisterName:@"size"]));
    builder->CreateStore(ConstantPointerNull::get(aProgram.llInt8PtrTy), builder->CreateStructGEP(alloca, 4, [self _llvmRegisterName:@"marked_variable"]));

    _alloca = alloca;

    return _alloca;
}
- (llvm::Value *)generateCodeInProgram:(TQProgram *)aProgram
                                 block:(TQNodeBlock *)aBlock
                                 error:(NSError **)aoError
{
    if(_alloca)
        return [self _getForwardingInProgram:aProgram block:aBlock];

    if(![self createStorageInProgram:aProgram block:aBlock error:aoError])
        return NULL;

    return [self _getForwardingInProgram:aProgram block:aBlock];
}

- (llvm::Value *)store:(llvm::Value *)aValue
             inProgram:(TQProgram *)aProgram
                 block:(TQNodeBlock *)aBlock
                 error:(NSError **)aoError
{
    if(!_alloca) {
        if(![self createStorageInProgram:aProgram block:aBlock error:aoError])
            return NULL;
    }
    IRBuilder<> *builder = aBlock.builder;

    Value *forwarding = builder->CreateLoad(builder->CreateStructGEP(_alloca, 1), [self _llvmRegisterName:@"forwarding"]);<commit_msg>Made variables be initialized at the beginning of their creating block (It's both more correct, and fixes the case where if an uninitialized variable is used within a flow control block, that is never executed it would have a garbage value)<commit_after>#import "TQNodeVariable.h"
#import "../TQProgram.h"
#import "../TQDebug.h"
#import <llvm/IRBuilder.h>

using namespace llvm;

@interface TQNodeVariable (Private)
- (TQNodeVariable *)_getExistingIdenticalInBlock:(TQNodeBlock *)aBlock;
- (const char *)_llvmRegisterName:(NSString *)subname;
@end

@implementation TQNodeVariable
@synthesize name=_name, alloca=_alloca, forwarding=_forwarding;

+ (TQNodeVariable *)nodeWithName:(NSString *)aName
{
    return [[[self alloc] initWithName:aName] autorelease];
}

- (id)initWithName:(NSString *)aName
{
    if(!(self = [super init]))
        return nil;

    _name = [aName retain];

    return self;
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"<var@ %@>", _name ? _name : @"unnamed"];
}

- (NSUInteger)hash
{
    return [_name hash];
}

- (BOOL)isEqual:(id)aObj
{
    if([aObj isKindOfClass:[TQNodeVariable class]] && [[(TQNodeVariable *)aObj name] isEqualToString:_name])
        return YES;
    else
        return NO;
}
- (TQNode *)referencesNode:(TQNode *)aNode
{
    return [aNode isEqual:self] ? self : nil;
}


- (void)dealloc
{
    [_name release];
    [super dealloc];
}

- (llvm::Value *)_getForwardingInProgram:(TQProgram *)aProgram block:(TQNodeBlock *)aBlock
{
    TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
    if(existingVar)
        return [existingVar _getForwardingInProgram:aProgram block:aBlock];

    IRBuilder<> *builder = aBlock.builder;
    Value *forwarding;
    forwarding = builder->CreateLoad(builder->CreateStructGEP(_alloca, 1), [self _llvmRegisterName:@"forwardingPtr"]);
    forwarding = builder->CreateBitCast(forwarding, PointerType::getUnqual([self captureStructTypeInProgram:aProgram]), [self _llvmRegisterName:@"forwarding"]);

    return builder->CreateLoad(builder->CreateStructGEP(forwarding, 4));
}

- (llvm::Type *)captureStructTypeInProgram:(TQProgram *)aProgram
{
    static Type *captureType = NULL;
    if(captureType)
        return captureType;

    Type *i8PtrTy = aProgram.llInt8PtrTy;
    Type *intTy   = aProgram.llIntTy;

    captureType = StructType::create("struct._block_byref",
                                     i8PtrTy, // isa
                                     i8PtrTy, // forwarding
                                     intTy,   // flags (refcount)
                                     intTy,   // size ( = sizeof(id))
                                     i8PtrTy, // Captured variable (id)
                                     NULL);
    return captureType;
}

- (const char *)_llvmRegisterName:(NSString *)subname
{
    return _name ? [[NSString stringWithFormat:@"%@.%@", _name, subname] UTF8String] : "";
}

- (llvm::Value *)createStorageInProgram:(TQProgram *)aProgram
                                 block:(TQNodeBlock *)aBlock
                                 error:(NSError **)aoError
{
    if(_alloca)
        return _alloca;

    IRBuilder<> *builder = aBlock.builder;
    TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
    if(existingVar) {
        if(![existingVar generateCodeInProgram:aProgram block:aBlock error:aoError])
            return NULL;
        _alloca = existingVar.alloca;

        return _alloca;
    }
    Type *intTy   = aProgram.llIntTy;
    Type *i8PtrTy = aProgram.llInt8PtrTy;

    Type *byRefType = [self captureStructTypeInProgram:aProgram];
    IRBuilder<> entryBuilder(&aBlock.function->getEntryBlock(), aBlock.function->getEntryBlock().begin());
    AllocaInst *alloca = entryBuilder.CreateAlloca(byRefType, 0, [self _llvmRegisterName:@"alloca"]);

    // Initialize the variable to nil
    entryBuilder.CreateStore(builder->CreateBitCast(alloca, i8PtrTy),        builder->CreateStructGEP(alloca, 1, [self
    _llvmRegisterName:@"forwardingAssign"]));
    entryBuilder.CreateStore(ConstantInt::get(intTy, 0), builder->CreateStructGEP(alloca, 2, [self _llvmRegisterName:@"flags"]));
    Constant *size = ConstantExpr::getTruncOrBitCast(ConstantExpr::getSizeOf(byRefType), intTy);
    entryBuilder.CreateStore(size,                                           builder->CreateStructGEP(alloca, 3, [self _llvmRegisterName:@"size"]));
    entryBuilder.CreateStore(ConstantPointerNull::get(aProgram.llInt8PtrTy), builder->CreateStructGEP(alloca, 4, [self _llvmRegisterName:@"marked_variable"]));

    _alloca = alloca;

    return _alloca;
}
- (llvm::Value *)generateCodeInProgram:(TQProgram *)aProgram
                                 block:(TQNodeBlock *)aBlock
                                 error:(NSError **)aoError
{
    if(_alloca)
        return [self _getForwardingInProgram:aProgram block:aBlock];

    if(![self createStorageInProgram:aProgram block:aBlock error:aoError])
        return NULL;

    return [self _getForwardingInProgram:aProgram block:aBlock];
}

- (llvm::Value *)store:(llvm::Value *)aValue
             inProgram:(TQProgram *)aProgram
                 block:(TQNodeBlock *)aBlock
                 error:(NSError **)aoError
{
    if(!_alloca) {
        if(![self createStorageInProgram:aProgram block:aBlock error:aoError])
            return NULL;
    }
    IRBuilder<> *builder = aBlock.builder;

    Value *forwarding = builder->CreateLoad(builder->CreateStructGEP(_alloca, 1), [self _llvmRegisterName:@"forwarding"]);
{'fraction_non_alphanumeric': 0.12450318883445789, 'fraction_numerical': 0.0035123394029023015, 'mean_word_length': 3.2348336594911937, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6875634', 'n_tokens_mistral': 3388, 'n_tokens_neox': 3202, 'n_words': 627}