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

using namespace llvm;

@interface TQNodeVariable (Private)
- (TQNodeVariable *)_getExistingIdenticalInBlock:(TQNodeBlock *)aBlock;
@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];
}

- (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
{
	if(_forwarding)
		return _forwarding;

	TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
	if(existingVar) {
		if(![existingVar _getForwardingInProgram:aProgram block:aBlock])
			return NULL;
		_forwarding = existingVar.forwarding;
		return _forwarding;
	}

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

	return _forwarding;
}

- (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, // byref_keep(void *dest, void *src)
	                                 i8PtrTy, // byref_dispose(void *)
	                                 i8PtrTy, // Captured variable (id)
	                                 NULL);
	return captureType;
}
<commit_msg>Fixed multiple assignments to a var<commit_after>#import "TQNodeVariable.h"
#import "TQProgram.h"
#import <llvm/Support/IRBuilder.h>

using namespace llvm;

@interface TQNodeVariable (Private)
- (TQNodeVariable *)_getExistingIdenticalInBlock:(TQNodeBlock *)aBlock;
@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];
}

- (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
{
	IRBuilder<> *builder = aBlock.builder;

	if(!_forwarding) {
		TQNodeVariable *existingVar = [self _getExistingIdenticalInBlock:aBlock];
		if(existingVar) {
			if(![existingVar _getForwardingInProgram:aProgram block:aBlock])
				return NULL;
			_forwarding = existingVar.forwarding;
		} else {
		_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, 6));
}

- (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, // byref_keep(void *dest, void *src)
	                                 i8PtrTy, // byref_dispose(void *)
	                                 i8PtrTy, // Captured variable (id)
	                                 NULL);
	return captureType;
}

{'fraction_non_alphanumeric': 0.1282100421617478, 'fraction_numerical': 0.0034495975469528554, 'mean_word_length': 3.3311203319502076, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5754628', 'n_tokens_mistral': 1787, 'n_tokens_neox': 1676, 'n_words': 322}