tim Rowledge uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-tpr.290.mcz
==================== Summary ====================
Name: VMMaker.oscog-tpr.290 Author: tpr Time: 15 May 2013, 1:05:58.213 pm UUID: 31707f84-deff-4c57-8d55-df4e7407682f Ancestors: VMMaker.oscog-tpr.289
Clean up some global struct code; - remove need to build separate sources to accomodate use of register global ptr to struct - clean up recording/testing for use of global struct in methods - define USE_GLOBAL_STRUCT_REG to use the global struct reg; right now machine factors require a different define for each machine/OS. Maybe this can be improved
=============== Diff against VMMaker.oscog-tpr.289 ===============
Item was changed: ----- Method: CCodeGenerator>>checkForGlobalUsage:in: (in category 'utilities') ----- checkForGlobalUsage: vars in: aTMethod vars do: [:var | (variables includes: var) ifTrue: "find the set of method names using this global var" [(globalVariableUsage at: var ifAbsentPut: [Set new]) add: aTMethod selector]]. + aTMethod clearReferencesToGlobalStruct. - aTMethod referencesGlobalStructMakeZero. (aTMethod locals select: [:l| self reservedWords includes: l]) do: [:l| | em | em := aTMethod definingClass name, '>>', aTMethod selector, ' has variable that is a C reserved word: ', l. self error: em. self logger cr; nextPutAll: em; cr; flush]!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>checkForGlobalUsage:in: (in category 'utilities') ----- checkForGlobalUsage: vars in: aTMethod "override to handle global struct needs" super checkForGlobalUsage: vars in: aTMethod. + - "if localStructDef is false, we don't ever need to include a reference to it in a function" - localStructDef ifFalse:[^self]. vars asSet do: [:var | "if any var is global and in the global var struct + tell the TMethod it may be refering to the struct, depending upon the #defines" - tell the TMethod it will be refering to the struct" ((variables includes: var) and: [self placeInStructure: var]) ifTrue: + [aTMethod referencesGlobalStruct]]! - [aTMethod referencesGlobalStructIncrementBy: (vars occurrencesOf: var)]]!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>emitCCodeOn:doInlining:doAssertions: (in category 'C code generator') ----- emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag super emitCCodeOn: aStream doInlining: inlineFlag doAssertions: assertionFlag.
+ "we add an initialiser for the pointer to the global struct; " + aStream + cr; + nextPutAll: 'void initGlobalStructure(void) {';cr; + nextPutAll: '#if SQ_USE_GLOBAL_STRUCT_REG';cr; + nextPutAll: 'foo = &fum;' ; cr; + nextPutAll: '#endif'; cr; + nextPutAll:'}'; + cr! - "if the machine needs the globals structure defined locally in the interp.c file, don't add the folowing function" - localStructDef ifFalse:[self emitStructureInitFunctionOn: aStream]!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>emitCVariablesOn: (in category 'C code generator') ----- emitCVariablesOn: aStream "Store the global variable declarations on the given stream. Break logic into vars for structure and vars for non-structure." | structure nonstruct |
structure := WriteStream on: (String new: 32768). nonstruct := WriteStream on: (String new: 32768). aStream nextPutAll: '/*** Variables ***/'; cr. structure nextPutAll: '#if SQ_USE_GLOBAL_STRUCT'; cr; nextPutAll: '# define _iss /* define in-struct static as void */'; cr; nextPutAll: 'static struct foo {'; cr; nextPutAll: '#else'; cr; nextPutAll: '# define _iss static'; cr; nextPutAll: '#endif'; cr. self buildSortedVariablesCollection do: [ :var | | decl varString inStruct target | target := (inStruct := self placeInStructure: (varString := var asString)) ifTrue: [structure] ifFalse: [nonstruct]. decl := variableDeclarations at: varString ifAbsent: ['sqInt ' , varString]. decl first == $# "support cgen var: #bytecodeSetSelector declareC: '#define bytecodeSetSelector 0' hack" ifTrue: [target nextPutAll: decl; cr] ifFalse: [self isGeneratingPluginCode ifTrue: [varString = 'interpreterProxy' ifTrue: "quite special..." [self preDeclareInterpreterProxyOn: target] ifFalse: [target nextPutAll: 'static ']] ifFalse: [(vmClass mustBeGlobal: varString) ifFalse: [target nextPutAll: (inStruct ifTrue: ['_iss '] ifFalse: ['static '])]]. target nextPutAll: decl; nextPut: $;; cr]]. structure nextPutAll: '#undef _iss'; cr; nextPutAll: '#if SQ_USE_GLOBAL_STRUCT'; cr; nextPutAll: ' } fum;'; cr; + nextPutAll: ' #if SQ_USE_GLOBAL_STRUCT_REGISTER';cr; + nextPutAll: '# define DECL_MAYBE_SQ_GLOBAL_STRUCT /* using a global reg pointer */'; cr; + nextPutAll: '# define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT /* using a global reg pointer */'; cr; + nextPutAll:'#else';cr; nextPutAll: '# define DECL_MAYBE_SQ_GLOBAL_STRUCT register struct foo * foo = &fum;'; cr; nextPutAll: '# define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT volatile register struct foo * foo = &fum;'; cr; + nextPutAll: '#endif';cr; nextPutAll: '# define GIV(interpreterInstVar) (foo->interpreterInstVar)'; cr; nextPutAll: '#else'; cr; nextPutAll: '# define DECL_MAYBE_SQ_GLOBAL_STRUCT /* oh, no mr bill!! */'; cr; nextPutAll: '# define DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT /* oh no, mr bill!! */'; cr; nextPutAll: '# define GIV(interpreterInstVar) interpreterInstVar'; cr; nextPutAll: '#endif'; cr.
+ "if the machine needs the fum structure defining locally, do it now; global register users don't need this" + structure + nextPutAll: '#if SQ_USE_GLOBAL_STRUCT'; cr; + nextPutAll: '#if SQ_USE_GLOBAL_STRUCT_REGISTER';cr; + nextPutAll: 'register struct foo * foo asm("USE_GLOBAL_STRUCT_REG")'; cr; + nextPutAll: '#else'; cr; + nextPutAll: 'static struct foo * foo = &fum;'; cr; + nextPutAll: '#endif'; cr; + nextPutAll: '#endif'; cr. - "if the machine needs the fum structure defining locally, do it now" - localStructDef ifTrue: - [structure - nextPutAll: '#if SQ_USE_GLOBAL_STRUCT'; cr; - nextPutAll: 'static struct foo * foo = &fum;'; cr; - nextPutAll: '#endif'; cr].
aStream nextPutAll: structure contents; nextPutAll: nonstruct contents; cr!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>emitGlobalStructFlagOn: (in category 'C code generator') ----- emitGlobalStructFlagOn: aStream + "Depending upon the value of structDefDefine (See also #structDefDefine:), define SQ_USE_GLOBAL_STRUCT before including the header. Also derive the flag for using the global register; define USE_GLOBAL_STRUCT_REG to do so" - "Define SQ_USE_GLOBAL_STRUCT before including the header."
aStream nextPutAll: '#if '; nextPutAll: structDefDefine; cr; nextPutAll: '# define SQ_USE_GLOBAL_STRUCT 1'; cr; nextPutAll: '#else'; cr; nextPutAll: '# define SQ_USE_GLOBAL_STRUCT 0'; cr; nextPutAll: '#endif'; cr; + nextPutAll: '#if USE_GLOBAL_STRUCT_REG '; cr; + nextPutAll: '# define SQ_USE_GLOBAL_STRUCT_REG 1'; cr; + nextPutAll: '#else'; cr; + nextPutAll: '# define SQ_USE_GLOBAL_STRUCT_REG 0'; cr; + nextPutAll: '#endif'; cr; cr!
Item was removed: - ----- Method: CCodeGeneratorGlobalStructure>>emitStructureInitFunctionOn: (in category 'C code generator') ----- - emitStructureInitFunctionOn: aStream - "For the VM using a global struct for most of the global vars (useful for ARM and PPC so far), append the initGlobalStructure() function" - aStream - cr; - nextPutAll: 'void initGlobalStructure(void) {foo = &fum;}'; - cr!
Item was removed: - ----- Method: CCodeGeneratorGlobalStructure>>globalStructDefined: (in category 'C code generator') ----- - globalStructDefined: aBool - localStructDef := aBool!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>initialize (in category 'C code generator') ----- initialize super initialize. + localStructDef := nil. "ignored ivar - no longer used" - localStructDef := false. structDefDefine := '1'!
Item was changed: ----- Method: CCodeGeneratorGlobalStructure>>structDefDefine: (in category 'initialize-release') ----- structDefDefine: aString + "set the string that will appear in the C file to define whether or not to use the global struct; reasonable values would be: + 'USE_GLOBAL_STRUCT' - which would be defined in a header or makefile + '0' - which would mean never do it + '1' - which would mean always do it" structDefDefine := aString!
Item was changed: ----- Method: CrossPlatformVMMaker>>createCodeGenerator (in category 'initialize') ----- createCodeGenerator "Set up a CCodeGenerator for this VMMaker - A cross platform tree leaves it up to the makefiles to decide whether to use the global struct or not." ^CCodeGeneratorGlobalStructure new initialize; - globalStructDefined: true; structDefDefine: 'USE_GLOBAL_STRUCT'; logger: logger; options: optionsDictionary; yourself!
Item was changed: ----- Method: MacOSPowerPCOS9VMMaker>>createCodeGenerator (in category 'initialize') ----- createCodeGenerator "Set up a CCodeGenerator for this VMMaker - Mac OS uses the global struct and local def of the structure. The global struct/loca def regime appears to be about 10% faster than the default regime for Smalltalk-intensive macro benchmarks for both the Intel and gcc 4.0 compiler on x86. eem 12/10/2008 14:34 2.16 GHz Intel Core Duo MacBook Pro Mac OS X 10.4.11" ^CCodeGeneratorGlobalStructure new initialize; - globalStructDefined: true; structDefDefine: '1'; "structDefDefine: 'defined(PPC) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__)';" logger: logger; yourself!
Item was changed: ----- Method: RiscOSVMMaker>>createCodeGenerator (in category 'initialize') ----- createCodeGenerator "set up a CCodeGenerator for this VMMaker - RiscOS uses the global struct and no local def of the structure because of the global register trickery" ^CCodeGeneratorGlobalStructure new initialize; - globalStructDefined: false; logger: logger; yourself!
Item was added: + ----- Method: TMethod>>clearReferencesToGlobalStruct (in category 'accessing') ----- + clearReferencesToGlobalStruct + globalStructureBuildMethodHasFoo := false!
Item was changed: ----- Method: TMethod>>emitCLocalsOn:generator: (in category 'C code generation') ----- emitCLocalsOn: aStream generator: aCodeGen "Emit a C function header for this method onto the given stream."
| volatileVariables | volatileVariables := properties includesKey: #volatile. + self refersToGlobalStruct ifTrue: - self globalStructureBuildMethodHasFoo > 1 ifTrue: [aStream next: 3 put: Character space; "there's already an opening ${ on this line; see sender" nextPutAll: (volatileVariables ifTrue: ['DECL_MAYBE_VOLATILE_SQ_GLOBAL_STRUCT'] ifFalse: ['DECL_MAYBE_SQ_GLOBAL_STRUCT'])]. aStream cr. locals isEmpty ifFalse: [(aCodeGen sortStrings: locals) do: [ :var | aStream next: 4 put: Character space. volatileVariables ifTrue: [aStream nextPutAll: #volatile; space]. aStream nextPutAll: (self declarationAt: var); nextPut: $;; cr]. aStream cr]!
Item was removed: - ----- Method: TMethod>>globalStructureBuildMethodHasFoo (in category 'accessing') ----- - globalStructureBuildMethodHasFoo - ^globalStructureBuildMethodHasFoo!
Item was added: + ----- Method: TMethod>>referencesGlobalStruct (in category 'accessing') ----- + referencesGlobalStruct + globalStructureBuildMethodHasFoo := true!
Item was removed: - ----- Method: TMethod>>referencesGlobalStructIncrementBy: (in category 'accessing') ----- - referencesGlobalStructIncrementBy: value - globalStructureBuildMethodHasFoo := globalStructureBuildMethodHasFoo + value.!
Item was removed: - ----- Method: TMethod>>referencesGlobalStructMakeZero (in category 'accessing') ----- - referencesGlobalStructMakeZero - globalStructureBuildMethodHasFoo := 0!
Item was added: + ----- Method: TMethod>>refersToGlobalStruct (in category 'accessing') ----- + refersToGlobalStruct + ^globalStructureBuildMethodHasFoo!
Item was changed: ----- Method: TMethod>>setSelector:definingClass:args:locals:block:primitive:properties:comment: (in category 'initialization') ----- setSelector: sel definingClass: class args: argList locals: localList block: aBlockNode primitive: aNumber properties: methodProperties comment: aComment "Initialize this method using the given information."
selector := sel. definingClass := class. returnType := #sqInt. "assume return type is long for now" args := argList asOrderedCollection collect: [:arg | arg key]. locals := (localList collect: [:arg | arg key]) asSet. declarations := Dictionary new. self addTypeForSelf. primitive := aNumber. properties := methodProperties. comment := aComment. parseTree := aBlockNode. "hack; allows nodes to find their parent, etc" parseTree := aBlockNode asTranslatorNodeIn: self. labels := OrderedCollection new. complete := false. "set to true when all possible inlining has been done" export := self extractExportDirective. static := self extractStaticDirective. canAsmLabel := self extractLabelDirective. self extractSharedCase. self removeFinalSelfReturn. "must preceed recordDeclarations because this may set returnType" self recordDeclarations. + globalStructureBuildMethodHasFoo := false! - globalStructureBuildMethodHasFoo := 0!
Item was changed: ----- Method: UnixVMMaker>>createCodeGenerator (in category 'initialisation') ----- createCodeGenerator
^CCodeGeneratorGlobalStructure new initialize; - globalStructDefined: true; logger: logger; yourself!
Item was changed: ----- Method: Win32VMMaker>>createCodeGenerator (in category 'initialize') ----- createCodeGenerator "Set up a CCodeGenerator for this VMMaker - On Windows we use the gcc 2.95.x compiler which does better without the global struct." ^CCodeGeneratorGlobalStructure new initialize; - globalStructDefined: true; structDefDefine: '0'; "structDefDefine: 'defined(PPC) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__)';" logger: logger; yourself!
vm-dev@lists.squeakfoundation.org